static bool _mongoc_matcher_op_lte_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { int code; BSON_ASSERT (compare); BSON_ASSERT (iter); code = _TYPE_CODE (bson_iter_type (&compare->iter), bson_iter_type (iter)); switch (code) { /* Double on Left Side */ case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): return _LTE_COMPARE (_double, _double); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): return _LTE_COMPARE (_double, _bool); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT32): return _LTE_COMPARE (_double, _int32); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT64): return _LTE_COMPARE (_double, _int64); /* Int32 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_DOUBLE): return _LTE_COMPARE (_int32, _double); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_BOOL): return _LTE_COMPARE (_int32, _bool); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT32): return _LTE_COMPARE (_int32, _int32); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT64): return _LTE_COMPARE (_int32, _int64); /* Int64 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_DOUBLE): return _LTE_COMPARE (_int64, _double); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_BOOL): return _LTE_COMPARE (_int64, _bool); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT32): return _LTE_COMPARE (_int64, _int32); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT64): return _LTE_COMPARE (_int64, _int64); default: MONGOC_WARNING ("Implement for (Type(%d) <= Type(%d))", bson_iter_type (&compare->iter), bson_iter_type (iter)); break; } return false; }
bool _mongoc_convert_validate_flags (mongoc_client_t *client, const bson_iter_t *iter, bson_validate_flags_t *flags, bson_error_t *error) { if (BSON_ITER_HOLDS_BOOL (iter)) { if (!bson_iter_as_bool (iter)) { *flags = BSON_VALIDATE_NONE; return true; } else { /* validate: false is ok but validate: true is prohibited */ CONVERSION_ERR ("Invalid option \"%s\": true, must be a bitwise-OR of" " bson_validate_flags_t values.", bson_iter_key (iter)); } } else if (BSON_ITER_HOLDS_INT32 (iter)) { if (bson_iter_int32 (iter) <= 0x1F) { *flags = (bson_validate_flags_t) bson_iter_int32 (iter); return true; } else { CONVERSION_ERR ("Invalid field \"%s\" in opts, must be a bitwise-OR of" " bson_validate_flags_t values.", bson_iter_key (iter)); } } CONVERSION_ERR ("Invalid type for option \"%s\": \"%s\"." " \"%s\" must be a boolean or a bitwise-OR of" " bson_validate_flags_t values.", bson_iter_key (iter), _mongoc_bson_type_to_str (bson_iter_type (iter)), bson_iter_key (iter)); }
bool _mongoc_convert_int64_positive (mongoc_client_t *client, const bson_iter_t *iter, int64_t *num, bson_error_t *error) { int64_t i; if (!BSON_ITER_HOLDS_NUMBER (iter)) { CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain number," " not %s", bson_iter_key (iter), _mongoc_bson_type_to_str (bson_iter_type (iter))); } i = bson_iter_as_int64 (iter); if (i <= 0) { CONVERSION_ERR ("Invalid field \"%s\" in opts, should be greater than 0," " not %" PRId64, bson_iter_key (iter), i); } *num = bson_iter_as_int64 (iter); return true; }
int monary_load_size_value(const bson_iter_t* bsonit, monary_column_item* citem, int idx) { bson_type_t type; const uint8_t* discard; uint32_t size; uint32_t* dest; type = bson_iter_type(bsonit); switch (type) { case BSON_TYPE_UTF8: case BSON_TYPE_CODE: bson_iter_utf8(bsonit, &size); break; case BSON_TYPE_BINARY: bson_iter_binary(bsonit, NULL, &size, &discard); break; case BSON_TYPE_DOCUMENT: bson_iter_document(bsonit, &size, &discard); break; case BSON_TYPE_ARRAY: bson_iter_array(bsonit, &size, &discard); break; default: return 0; } dest = ((uint32_t*) citem->storage) + idx; memcpy(dest, &size, sizeof(uint32_t)); return 1; }
bool _mongoc_convert_document (mongoc_client_t *client, const bson_iter_t *iter, bson_t *doc, bson_error_t *error) { uint32_t len; const uint8_t *data; bson_t value; if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain document," " not %s", bson_iter_key (iter), _mongoc_bson_type_to_str (bson_iter_type (iter))); } bson_iter_document (iter, &len, &data); if (!bson_init_static (&value, data, len)) { BSON_ERR ("Corrupt BSON in field \"%s\" in opts", bson_iter_key (iter)); } bson_destroy (doc); bson_copy_to (&value, doc); return true; }
//Casts to an int int get_bson_int(const bson_t *obj, char *name) { bson_iter_t i; bson_iter_t t; if (bson_iter_init(&i, obj)) { if (bson_iter_find_descendant(&i, name, &t)) { if (bson_iter_type(&t) == BSON_TYPE_INT32) { return bson_iter_int32(&t); } if (bson_iter_type(&t) == BSON_TYPE_DOUBLE) { return (int) bson_iter_double(&t); } } } return 0; }
bson::type element::type() const { if (_raw == nullptr) { return bson::type::k_eod; } CITER; return static_cast<bson::type>(bson_iter_type(&iter)); }
bsoncxx::type element::type() const { if (_raw == nullptr) { throw bsoncxx::exception{error_code::k_unset_element}; } BSONCXX_CITER; return static_cast<bsoncxx::type>(bson_iter_type(&iter)); }
int monary_load_type_value(const bson_iter_t* bsonit, monary_column_item* citem, int idx) { uint8_t type; uint8_t* dest; type = (uint8_t) bson_iter_type(bsonit); dest = ((uint8_t*) citem->storage) + idx; memcpy(dest, &type, sizeof(uint8_t)); return 1; }
static bool bson_metrics_visit_before (const bson_iter_t *iter, const char *key, void *data) { bson_metrics_state_t *state = data; bson_type_t btype; ++state->element_count; state->key_size_tally += strlen(key); /* TODO - filter out array keys(?) */ btype = bson_iter_type (iter); ++state->bson_type_metrics[btype].count; return false; }
const char *get_bson_string(const bson_t *obj, char *name) { bson_iter_t i; bson_type_t t; unsigned int length; if (bson_iter_init(&i, obj)) { if (bson_iter_find(&i, name)) { if (bson_iter_type(&i) == BSON_TYPE_UTF8) { return bson_iter_utf8(&i, &length); } } } return NULL; }
bool _mongoc_convert_bool (mongoc_client_t *client, const bson_iter_t *iter, bool *flag, bson_error_t *error) { if (BSON_ITER_HOLDS_BOOL (iter)) { *flag = bson_iter_bool (iter); return true; } CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain bool," " not %s", bson_iter_key (iter), _mongoc_bson_type_to_str (bson_iter_type (iter))); }
bool _mongoc_convert_utf8 (mongoc_client_t *client, const bson_iter_t *iter, const char **str, bson_error_t *error) { if (BSON_ITER_HOLDS_UTF8 (iter)) { *str = bson_iter_utf8 (iter, NULL); return true; } CONVERSION_ERR ("Invalid field \"%s\" in opts, should contain string," " not %s", bson_iter_key (iter), _mongoc_bson_type_to_str (bson_iter_type (iter))); }
static bool _mongoc_matcher_op_type_match (mongoc_matcher_op_type_t *type, /* IN */ const bson_t *bson) /* IN */ { bson_iter_t iter; bson_iter_t desc; BSON_ASSERT (type); BSON_ASSERT (bson); if (bson_iter_init (&iter, bson) && bson_iter_find_descendant (&iter, type->path, &desc)) { return (bson_iter_type (&iter) == type->type); } return false; }
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; }
static bool decode_visit_before(const bson_iter_t *iter, const char *key, void *data) { decode_state *ds = data; ERL_NIF_TERM out; LOG("decode visit key: %s, type: %d\r\n", key, bson_iter_type(iter)); if(ds->keys) { if(!make_binary(ds->env, &out, key, strlen(key))) { return true; } vec_push(ds->vec, out); } return false; }
static void test_iter (void) { bson_iter_t iter; bson_t *other; bson_t *bcon = BCON_NEW ("foo", BCON_INT32 (10)); assert (BCON_EXTRACT (bcon, "foo", BCONE_ITER (iter))); assert (bson_iter_type (&iter) == BSON_TYPE_INT32); assert (bson_iter_int32 (&iter) == 10); other = BCON_NEW ("foo", BCON_ITER (&iter)); bson_eq_bson (other, bcon); bson_destroy (bcon); bson_destroy (other); }
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)); } }
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)); } }
// 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; }
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; }
int BsonIterType(BSON_ITERATOR *it) { return bson_iter_type(it); }
static void test_bson_iter_fuzz (void) { uint8_t *data; uint32_t len = 512; uint32_t len_le; uint32_t r; bson_iter_t iter; bson_t *b; uint32_t i; int pass; len_le = BSON_UINT32_TO_LE(len); for (pass = 0; pass < FUZZ_N_PASSES; pass++) { data = bson_malloc0(len); memcpy(data, &len_le, sizeof (len_le)); for (i = 4; i < len; i += 4) { r = rand(); memcpy(&data[i], &r, sizeof (r)); } if (!(b = bson_new_from_data(data, len))) { /* * It could fail on buffer length or missing trailing null byte. */ bson_free (data); continue; } BSON_ASSERT(b); /* * TODO: Most of the following ignores the key. That should be fixed * but has it's own perils too. */ assert(bson_iter_init(&iter, b)); while (bson_iter_next(&iter)) { assert(iter.next_off < len); switch (bson_iter_type(&iter)) { case BSON_TYPE_ARRAY: case BSON_TYPE_DOCUMENT: { const uint8_t *child = NULL; uint32_t child_len = 0; bson_iter_document(&iter, &child_len, &child); if (child_len) { assert(child); assert(child_len >= 5); assert((iter.off + child_len) < b->len); assert(child_len < (uint32_t) -1); memcpy(&child_len, child, sizeof (child_len)); child_len = BSON_UINT32_FROM_LE(child_len); assert(child_len >= 5); } } break; case BSON_TYPE_DOUBLE: case BSON_TYPE_UTF8: case BSON_TYPE_BINARY: case BSON_TYPE_UNDEFINED: break; case BSON_TYPE_OID: assert(iter.off + 12 < iter.len); break; case BSON_TYPE_BOOL: case BSON_TYPE_DATE_TIME: case BSON_TYPE_NULL: case BSON_TYPE_REGEX: /* TODO: check for 2 valid cstring. */ case BSON_TYPE_DBPOINTER: case BSON_TYPE_CODE: case BSON_TYPE_SYMBOL: case BSON_TYPE_CODEWSCOPE: case BSON_TYPE_INT32: case BSON_TYPE_TIMESTAMP: case BSON_TYPE_INT64: case BSON_TYPE_DECIMAL128: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: break; case BSON_TYPE_EOD: default: /* Code should not be reached. */ assert(false); break; } } bson_destroy(b); bson_free(data); } }
int be_mongo_aclcheck(void *conf, const char *clientid, const char *username, const char *topic, int acc) { struct mongo_backend *handle = (struct mongo_backend *) conf; mongoc_collection_t *collection; mongoc_cursor_t *cursor; bson_error_t error; const bson_t *doc; bson_iter_t iter; int match = 0; const bson_oid_t *topic_lookup_oid = NULL; const char *topic_lookup_utf8 = NULL; int64_t topic_lookup_int64 = 0; bson_t query; bson_init(&query); bson_append_utf8(&query, handle->user_username_prop, -1, username, -1); collection = mongoc_client_get_collection(handle->client, handle->database, handle->user_coll); cursor = mongoc_collection_find_with_opts(collection, &query, NULL, NULL); if (!mongoc_cursor_error (cursor, &error) && mongoc_cursor_next (cursor, &doc)) { // First find any user[handle->user_topiclist_fk_prop] if (bson_iter_init_find(&iter, doc, handle->user_topiclist_fk_prop)) { bson_type_t loc_id_type = bson_iter_type(&iter); if (loc_id_type == BSON_TYPE_OID) { topic_lookup_oid = bson_iter_oid(&iter); } else if (loc_id_type == BSON_TYPE_INT32 || loc_id_type == BSON_TYPE_INT64) { topic_lookup_int64 = bson_iter_as_int64(&iter); } else if (loc_id_type == BSON_TYPE_UTF8) { topic_lookup_utf8 = bson_iter_utf8(&iter, NULL); } } // Look through the props from the beginning for user[handle->user_topics_prop] if (bson_iter_init_find(&iter, doc, handle->user_topics_prop)) { bson_type_t embedded_prop_type = bson_iter_type(&iter); if (embedded_prop_type == BSON_TYPE_ARRAY) { match = be_mongo_check_acl_topics_array(&iter, topic, clientid, username); } else if (embedded_prop_type == BSON_TYPE_DOCUMENT) { match = be_mongo_check_acl_topics_map(&iter, topic, acc, clientid, username); } } } if ((mongoc_cursor_error (cursor, &error)) && (match != 1)) { fprintf (stderr, "Cursor Failure: %s\n", error.message); } bson_destroy(&query); mongoc_cursor_destroy (cursor); mongoc_collection_destroy(collection); if (!match && (topic_lookup_oid != NULL || topic_lookup_int64 != 0 || topic_lookup_utf8 != NULL)) { bson_init(&query); if (topic_lookup_oid != NULL) { bson_append_oid(&query, handle->topiclist_key_prop, -1, topic_lookup_oid); } else if (topic_lookup_int64 != 0) { bson_append_int64(&query, handle->topiclist_key_prop, -1, topic_lookup_int64); } else if (topic_lookup_utf8 != NULL) { bson_append_utf8(&query, handle->topiclist_key_prop, -1, topic_lookup_utf8, -1); } collection = mongoc_client_get_collection(handle->client, handle->database, handle->topiclist_coll); cursor = mongoc_collection_find_with_opts(collection, &query, NULL, NULL); if (!mongoc_cursor_error (cursor, &error) && mongoc_cursor_next(cursor, &doc)) { bson_iter_init(&iter, doc); if (bson_iter_find(&iter, handle->topiclist_topics_prop)) { bson_type_t loc_prop_type = bson_iter_type(&iter); if (loc_prop_type == BSON_TYPE_ARRAY) { match = be_mongo_check_acl_topics_array(&iter, topic, clientid, username); } else if (loc_prop_type == BSON_TYPE_DOCUMENT) { match = be_mongo_check_acl_topics_map(&iter, topic, acc, clientid, username); } } else { _log(LOG_NOTICE, "[mongo] ACL check error - no topic list found for user (%s) in collection (%s)", username, handle->topiclist_coll); } } if ((mongoc_cursor_error (cursor, &error)) && (match != 1)) { fprintf (stderr, "Cursor Failure: %s\n", error.message); } bson_destroy(&query); mongoc_cursor_destroy(cursor); mongoc_collection_destroy(collection); } return (match) ? BACKEND_ALLOW : BACKEND_DEFER; }
static mongoc_matcher_op_t * _mongoc_matcher_parse_compare (bson_iter_t *iter, /* IN */ const char *path, /* IN */ bson_error_t *error) /* OUT */ { const char * key; mongoc_matcher_op_t * op = NULL, * op_child; bson_iter_t child; BSON_ASSERT (iter); BSON_ASSERT (path); if (bson_iter_type (iter) == BSON_TYPE_DOCUMENT) { if (!bson_iter_recurse (iter, &child) || !bson_iter_next (&child)) { bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Document contains no operations."); return NULL; } key = bson_iter_key (&child); if (key[0] != '$') { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_EQ, path, iter); } else if (strcmp(key, "$not") == 0) { if (!(op_child = _mongoc_matcher_parse_compare (&child, path, error))) { return NULL; } op = _mongoc_matcher_op_not_new (path, op_child); } else if (strcmp(key, "$gt") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_GT, path, &child); } else if (strcmp(key, "$gte") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_GTE, path, &child); } else if (strcmp(key, "$in") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_IN, path, &child); } else if (strcmp(key, "$lt") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_LT, path, &child); } else if (strcmp(key, "$lte") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_LTE, path, &child); } else if (strcmp(key, "$ne") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_NE, path, &child); } else if (strcmp(key, "$nin") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_NIN, path, &child); } else if (strcmp(key, "$exists") == 0) { op = _mongoc_matcher_op_exists_new (path, bson_iter_bool (&child)); } else if (strcmp(key, "$type") == 0) { op = _mongoc_matcher_op_type_new (path, bson_iter_type (&child)); } else { bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Invalid operator \"%s\"", key); return NULL; } } else { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_EQ, path, iter); } BSON_ASSERT (op); return op; }
void bsonToVariant(const bson_t* bson, Array* output) { bson_iter_t iter; bson_iter_init(&iter, bson); while (bson_iter_next(&iter)) { switch (bson_iter_type(&iter)) { case BSON_TYPE_INT32: bsonToInt32(&iter, output); break; case BSON_TYPE_INT64: bsonToInt64(&iter, output); break; case BSON_TYPE_BOOL: bsonToBool(&iter, output); break; case BSON_TYPE_UTF8: bsonToString(&iter, output); break; case BSON_TYPE_NULL: bsonToNull(&iter, output); break; case BSON_TYPE_DOUBLE: bsonToDouble(&iter, output); break; case BSON_TYPE_DOCUMENT: bsonToArray(&iter, output, true); break; case BSON_TYPE_ARRAY: bsonToArray(&iter, output, false); break; case BSON_TYPE_OID: bsonToMongoId(&iter, output); break; case BSON_TYPE_DATE_TIME: bsonToMongoDate(&iter, output); break; case BSON_TYPE_REGEX: bsonToMongoRegexp(&iter, output); break; case BSON_TYPE_TIMESTAMP: bsonToMongoTimestamp(&iter, output); break; case BSON_TYPE_CODE: bsonToMongoCode(&iter, output); break; case BSON_TYPE_CODEWSCOPE: bsonToMongoCodeWithScope(&iter, output); break; case BSON_TYPE_BINARY: bsonToMongoBinData(&iter, output); break; case BSON_TYPE_MAXKEY: bsonToMongoMaxKey(&iter, output); break; case BSON_TYPE_MINKEY: bsonToMongoMinKey(&iter, output); break; default: break; } } }
/*! * \brief Convert rows from mongodb to db API representation * \param _h database connection * \param _r database result set * \return 0 on success, negative on failure */ static int db_mongodb_convert_bson(const db1_con_t* _h, db1_res_t* _r, int _row, const bson_t *_rdoc) { static str dummy_string = {"", 0}; int col; db_mongodb_result_t *mgres; const char *colname; bson_type_t coltype; bson_iter_t riter; bson_iter_t citer; bson_iter_t *piter; db_val_t* dval; uint32_t i32tmp; bson_subtype_t subtype; bson_t *cdoc; mgres = (db_mongodb_result_t*)RES_PTR(_r); if(mgres->nrcols==0) { LM_ERR("no fields to convert\n"); return -1; } if(mgres->colsdoc==NULL) { cdoc = (bson_t*)_rdoc; } else { cdoc = (bson_t*)mgres->colsdoc; } if (!bson_iter_init (&citer, cdoc)) { LM_ERR("failed to initialize columns iterator\n"); return -3; } if(mgres->colsdoc) { if (!bson_iter_init (&riter, _rdoc)) { LM_ERR("failed to initialize result iterator\n"); return -3; } } if (db_allocate_row(_r, &(RES_ROWS(_r)[_row])) != 0) { LM_ERR("could not allocate row: %d\n", _row); return -2; } col = 0; while (bson_iter_next (&citer)) { if(col >= RES_COL_N(_r)) { LM_ERR("invalid number of columns (%d/%d)\n", col, RES_COL_N(_r)); return -4; } colname = bson_iter_key (&citer); LM_DBG("looking for field[%d] named: %s\n", col, colname); if(mgres->colsdoc) { if(!bson_iter_find(&riter, colname)) { LM_ERR("field [%s] not found in result iterator\n", colname); return -4; } piter = &riter; } else { piter = &citer; } coltype = bson_iter_type(piter); dval = &(ROW_VALUES(&(RES_ROWS(_r)[_row]))[col]); VAL_TYPE(dval) = RES_TYPES(_r)[col]; switch(coltype) { case BSON_TYPE_BOOL: VAL_INT(dval) = (int)bson_iter_bool (piter); break; case BSON_TYPE_INT32: VAL_INT(dval) = bson_iter_int32 (piter); break; case BSON_TYPE_TIMESTAMP: bson_iter_timestamp (piter, (uint32_t*)&VAL_INT(dval), &i32tmp); break; case BSON_TYPE_INT64: VAL_BIGINT(dval) = bson_iter_int64 (piter); break; case BSON_TYPE_DOUBLE: VAL_DOUBLE(dval) = bson_iter_double (piter); break; case BSON_TYPE_DATE_TIME: VAL_TIME(dval) = (time_t)(bson_iter_date_time (piter)/1000); break; case BSON_TYPE_BINARY: bson_iter_binary (piter, &subtype, (uint32_t*)&VAL_BLOB(dval).len, (const uint8_t**)&VAL_BLOB(dval).s); break; case BSON_TYPE_UTF8: VAL_STRING(dval) = (char*)bson_iter_utf8 (piter, &i32tmp); break; case BSON_TYPE_OID: break; case BSON_TYPE_NULL: memset(dval, 0, sizeof(db_val_t)); /* Initialize the string pointers to a dummy empty * string so that we do not crash when the NULL flag * is set but the module does not check it properly */ VAL_STRING(dval) = dummy_string.s; VAL_STR(dval) = dummy_string; VAL_BLOB(dval) = dummy_string; VAL_TYPE(dval) = RES_TYPES(_r)[col]; VAL_NULL(dval) = 1; break; #if 0 case BSON_TYPE_EOD: case BSON_TYPE_DOCUMENT: case BSON_TYPE_ARRAY: case BSON_TYPE_UNDEFINED: case BSON_TYPE_REGEX: case BSON_TYPE_DBPOINTER: case BSON_TYPE_CODE: case BSON_TYPE_SYMBOL: case BSON_TYPE_CODEWSCOPE: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: #endif default: LM_WARN("unhandled data type column (%.*s) type id (%d), " "use DB1_STRING as default\n", RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, coltype); RES_TYPES(_r)[col] = DB1_STRING; break; } LM_DBG("RES_NAMES(%p)[%d]=[%.*s] (%d)\n", RES_NAMES(_r)[col], col, RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, coltype); col++; } return 0; }
/*! * \brief Get and convert columns from a result * * Get and convert columns from a result, fills the result structure * with data from the database. * \param _h database connection * \param _r database result set * \return 0 on success, negative on failure */ int db_mongodb_get_columns(const db1_con_t* _h, db1_res_t* _r) { int col; db_mongodb_result_t *mgres; bson_iter_t riter; bson_iter_t citer; bson_t *cdoc; const char *colname; bson_type_t coltype; if ((!_h) || (!_r)) { LM_ERR("invalid parameter\n"); return -1; } mgres = (db_mongodb_result_t*)RES_PTR(_r); if(!mgres->rdoc) { mgres->nrcols = 0; return 0; } if(mgres->nrcols==0 || mgres->colsdoc==NULL) { mgres->nrcols = (int)bson_count_keys(mgres->rdoc); if(mgres->nrcols==0) { LM_ERR("no keys in bson document\n"); return -1; } cdoc = mgres->rdoc; } else { cdoc = mgres->colsdoc; } RES_COL_N(_r) = mgres->nrcols; if (!RES_COL_N(_r)) { LM_ERR("no columns returned from the query\n"); return -2; } else { LM_DBG("%d columns returned from the query\n", RES_COL_N(_r)); } if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) { RES_COL_N(_r) = 0; LM_ERR("could not allocate columns\n"); return -3; } if (!bson_iter_init (&citer, cdoc)) { LM_ERR("failed to initialize columns iterator\n"); return -3; } if(mgres->colsdoc) { if (!bson_iter_init (&riter, mgres->rdoc)) { LM_ERR("failed to initialize result iterator\n"); return -3; } } col = 0; while (bson_iter_next (&citer)) { if(col >= RES_COL_N(_r)) { LM_ERR("invalid number of columns (%d/%d)\n", col, RES_COL_N(_r)); return -4; } colname = bson_iter_key (&citer); LM_DBG("Found a field[%d] named: %s\n", col, colname); if(mgres->colsdoc) { if(!bson_iter_find(&riter, colname)) { LM_ERR("field [%s] not found in result iterator\n", colname); return -4; } coltype = bson_iter_type(&riter); } else { coltype = bson_iter_type(&citer); } RES_NAMES(_r)[col] = (str*)pkg_malloc(sizeof(str)); if (! RES_NAMES(_r)[col]) { LM_ERR("no private memory left\n"); db_free_columns(_r); return -4; } LM_DBG("allocate %lu bytes for RES_NAMES[%d] at %p\n", (unsigned long)sizeof(str), col, RES_NAMES(_r)[col]); /* pointer linked here is part of the result structure */ RES_NAMES(_r)[col]->s = (char*)colname; RES_NAMES(_r)[col]->len = strlen(colname); switch(coltype) { case BSON_TYPE_BOOL: case BSON_TYPE_INT32: case BSON_TYPE_TIMESTAMP: LM_DBG("use DB1_INT result type\n"); RES_TYPES(_r)[col] = DB1_INT; break; case BSON_TYPE_INT64: LM_DBG("use DB1_BIGINT result type\n"); RES_TYPES(_r)[col] = DB1_BIGINT; break; case BSON_TYPE_DOUBLE: LM_DBG("use DB1_DOUBLE result type\n"); RES_TYPES(_r)[col] = DB1_DOUBLE; break; case BSON_TYPE_DATE_TIME: LM_DBG("use DB1_DATETIME result type\n"); RES_TYPES(_r)[col] = DB1_DATETIME; break; case BSON_TYPE_BINARY: LM_DBG("use DB1_BLOB result type\n"); RES_TYPES(_r)[col] = DB1_BLOB; break; case BSON_TYPE_UTF8: LM_DBG("use DB1_STRING result type\n"); RES_TYPES(_r)[col] = DB1_STRING; break; #if 0 case BSON_TYPE_EOD: case BSON_TYPE_DOCUMENT: case BSON_TYPE_ARRAY: case BSON_TYPE_UNDEFINED: case BSON_TYPE_OID: case BSON_TYPE_NULL: case BSON_TYPE_REGEX: case BSON_TYPE_DBPOINTER: case BSON_TYPE_CODE: case BSON_TYPE_SYMBOL: case BSON_TYPE_CODEWSCOPE: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: #endif default: LM_INFO("unhandled data type column (%.*s) type id (%d), " "use DB1_STRING as default\n", RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, coltype); RES_TYPES(_r)[col] = DB1_STRING; break; } LM_DBG("RES_NAMES(%p)[%d]=[%.*s] (%d)\n", RES_NAMES(_r)[col], col, RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s, coltype); col++; } return 0; }
QVariantMap TBson::fromBson(const TBsonObject *obj) { QVariantMap ret; bson_iter_t it; const bson_t *bson = (const bson_t *)obj; bson_iter_init(&it, bson); while (bson_iter_next(&it)) { bson_type_t t = bson_iter_type(&it); QString key(bson_iter_key(&it)); switch (t) { case BSON_TYPE_EOD: return ret; break; case BSON_TYPE_DOUBLE: ret[key] = bson_iter_double(&it); break; case BSON_TYPE_UTF8: ret[key] = QString::fromUtf8(bson_iter_utf8(&it, nullptr)); break; case BSON_TYPE_ARRAY: { const uint8_t *docbuf = nullptr; uint32_t doclen = 0; bson_t sub[1]; bson_iter_array(&it, &doclen, &docbuf); if (bson_init_static(sub, docbuf, doclen)) { ret[key] = fromBson(sub).values(); } break; } case BSON_TYPE_DOCUMENT: { const uint8_t *docbuf = nullptr; uint32_t doclen = 0; bson_t sub[1]; bson_iter_document(&it, &doclen, &docbuf); if (bson_init_static(sub, docbuf, doclen)) { ret[key] = fromBson(sub); } break; } case BSON_TYPE_BINARY: { const uint8_t *binary = nullptr; bson_subtype_t subtype = BSON_SUBTYPE_BINARY; uint32_t len = 0; bson_iter_binary(&it, &subtype, &len, &binary); if (binary) { ret[key] = QByteArray((char *)binary, len); } break; } case BSON_TYPE_UNDEFINED: ret[key] = QVariant(); break; case BSON_TYPE_OID: { char oidhex[25]; bson_oid_to_string(bson_iter_oid(&it), oidhex); ret[key] = QString(oidhex); break; } case BSON_TYPE_BOOL: ret[key] = (bool)bson_iter_bool(&it); break; case BSON_TYPE_DATE_TIME: { #if QT_VERSION >= 0x040700 QDateTime date; date.setMSecsSinceEpoch(bson_iter_date_time(&it)); #else qint64 val = bson_iter_date_time(&it); qint64 days = val / 86400000; // 24*60*60*1000 int msecs = val % 86400000; QDate dt = QDate(1970, 1, 1).addDays(days); QTime tm = QTime(0, 0, 0).addMSecs(msecs); QDateTime date(dt, tm, Qt::UTC); #endif ret[key] = date; break; } case BSON_TYPE_NULL: ret[key] = QVariant(); break; case BSON_TYPE_REGEX: ret[key] = QRegExp(QLatin1String(bson_iter_regex(&it, nullptr))); break; case BSON_TYPE_CODE: ret[key] = QString(bson_iter_code(&it, nullptr)); break; case BSON_TYPE_SYMBOL: ret[key] = QString(bson_iter_symbol(&it, nullptr)); break; case BSON_TYPE_INT32: ret[key] = bson_iter_int32(&it); break; case BSON_TYPE_INT64: ret[key] = (qint64)bson_iter_int64(&it); break; case BSON_TYPE_CODEWSCOPE: // FALL THROUGH case BSON_TYPE_TIMESTAMP: // FALL THROUGH (internal use) // do nothing break; default: tError("fromBson() unknown type: %d", t); break; } //tSystemDebug("fromBson : t:%d key:%s = %s", t, qPrintable(key), qPrintable(ret[key].toString())); } return ret; }
static bool _mongoc_matcher_op_eq_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { int code; BSON_ASSERT (compare); BSON_ASSERT (iter); code = _TYPE_CODE (bson_iter_type (&compare->iter), bson_iter_type (iter)); switch (code) { /* Double on Left Side */ case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): return _EQ_COMPARE (_double, _double); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): return _EQ_COMPARE (_double, _bool); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT32): return _EQ_COMPARE (_double, _int32); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT64): return _EQ_COMPARE (_double, _int64); /* UTF8 on Left Side */ case _TYPE_CODE(BSON_TYPE_UTF8, BSON_TYPE_UTF8): { uint32_t llen; uint32_t rlen; const char *lstr; const char *rstr; lstr = bson_iter_utf8 (&compare->iter, &llen); rstr = bson_iter_utf8 (iter, &rlen); return ((llen == rlen) && (0 == memcmp (lstr, rstr, llen))); } /* Int32 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_DOUBLE): return _EQ_COMPARE (_int32, _double); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_BOOL): return _EQ_COMPARE (_int32, _bool); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT32): return _EQ_COMPARE (_int32, _int32); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT64): return _EQ_COMPARE (_int32, _int64); /* Int64 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_DOUBLE): return _EQ_COMPARE (_int64, _double); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_BOOL): return _EQ_COMPARE (_int64, _bool); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT32): return _EQ_COMPARE (_int64, _int32); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT64): return _EQ_COMPARE (_int64, _int64); /* Null on Left Side */ case _TYPE_CODE(BSON_TYPE_NULL, BSON_TYPE_NULL): case _TYPE_CODE(BSON_TYPE_NULL, BSON_TYPE_UNDEFINED): return true; default: return false; } }