Example #1
0
static bool
handle_ismaster (mock_server_t   *server,
                 mongoc_stream_t *client,
                 mongoc_rpc_t    *rpc,
                 const bson_t    *doc)
{
   bson_t reply_doc = BSON_INITIALIZER;
   time_t now = time (NULL);

   BSON_ASSERT (server);
   BSON_ASSERT (client);
   BSON_ASSERT (rpc);
   BSON_ASSERT (doc);

   bson_append_bool (&reply_doc, "ismaster", -1, server->isMaster);
   bson_append_int32 (&reply_doc, "maxBsonObjectSize", -1,
                      server->maxBsonObjectSize);
   bson_append_int32 (&reply_doc, "maxMessageSizeBytes", -1,
                      server->maxMessageSizeBytes);
   bson_append_int32 (&reply_doc, "minWireVersion", -1,
                      server->minWireVersion);
   bson_append_int32 (&reply_doc, "maxWireVersion", -1,
                      server->maxWireVersion);
   bson_append_double (&reply_doc, "ok", -1, 1.0);
   bson_append_time_t (&reply_doc, "localtime", -1, now);

   mock_server_reply_simple (server, client, rpc, MONGOC_REPLY_NONE, &reply_doc);

   bson_destroy (&reply_doc);

   return true;
}
Example #2
0
/* Saves accounting information */
static int mongo_account(void *instance, REQUEST *request)
{
	rlm_mongo_t *data = (rlm_mongo_t *)instance;
	bson b;
	bson_buffer buf;
	const char *attr;
	char value[MAX_STRING_LEN+1];
	VALUE_PAIR *vp = request->packet->vps;
        // shall we insert this packet or not
        int insert;

	bson_buffer_init(&buf);
	bson_append_new_oid(&buf, "_id");

	insert = 0;

	while (vp) {
		attr = vp->name;
		if ((strcmp(attr, "Acct-Status-Type") == 0) && ((strcmp(data->only_stop, "") != 0))) {
			if ((vp->vp_integer & 0xffffff) != 2) {
				break;
			} else {
				insert = 1;
			}
		}
		switch (vp->type) {
			case PW_TYPE_INTEGER:
				bson_append_int(&buf, attr, vp->vp_integer & 0xffffff);
				break;
			case PW_TYPE_BYTE:
			case PW_TYPE_SHORT:
				bson_append_int(&buf, attr, vp->vp_integer);
				break;
			case PW_TYPE_DATE:
				bson_append_time_t(&buf, attr, vp->vp_date);
				break;
			default:
				vp_prints_value(value, sizeof(value), vp, 0);
				bson_append_string(&buf, attr, value);
				// akh
				RDEBUG("mongo default insert %s", value);
				break;
		}
		vp = vp->next;
	}
	bson_from_buffer(&b, &buf);

	MONGO_TRY {
		if (insert == 1) {
			mongo_insert(conn, data->acct_base, &b);
			RDEBUG("accounting record was inserted");
		}
	} MONGO_CATCH {
		radlog(L_ERR, "mongo_insert failed");
		return RLM_MODULE_FAIL;
	}

	bson_destroy(&b);
	return RLM_MODULE_OK;
}
Example #3
0
int commit_inode(struct inode * e) {
    bson cond, doc;
    mongo * conn = get_conn();
    char istr[4];
    struct dirent * cde = e->dirents;
    int res;

    bson_init(&doc);
    bson_append_start_object(&doc, "$set");
    bson_append_start_array(&doc, "dirents");
    res = 0;
    while(cde) {
        bson_numstr(istr, res++);
        bson_append_string(&doc, istr, cde->path);
        cde = cde->next;
    }
    bson_append_finish_array(&doc);

    bson_append_int(&doc, "mode", e->mode);
    bson_append_long(&doc, "owner", e->owner);
    bson_append_long(&doc, "group", e->group);
    bson_append_long(&doc, "size", e->size);
    bson_append_time_t(&doc, "created", e->created);
    bson_append_time_t(&doc, "modified", e->modified);
    if(e->data && e->datalen > 0)
        bson_append_string_n(&doc, "data", e->data, e->datalen);
    bson_append_finish_object(&doc);
    bson_finish(&doc);

    bson_init(&cond);
    bson_append_oid(&cond, "_id", &e->oid);
    bson_finish(&cond);

    res = mongo_update(conn, inodes_name, &cond, &doc,
        MONGO_UPDATE_UPSERT, NULL);
    bson_destroy(&cond);
    bson_destroy(&doc);
    if(res != MONGO_OK) {
        fprintf(stderr, "Error committing inode %s\n",
            mongo_get_server_err_string(conn));
        return -EIO;
    }
    return 0;
}
Example #4
0
static void
test_bson_as_json (void)
{
   bson_oid_t oid;
   bson_decimal128_t decimal128;
   bson_t *b;
   bson_t *b2;
   char *str;
   size_t len;
   int i;

   decimal128.high = 0x3040000000000000ULL;
   decimal128.low  = 0x000000000000000B;
   bson_oid_init_from_string(&oid, "123412341234abcdabcdabcd");

   b = bson_new();
   assert(bson_append_utf8(b, "utf8", -1, "bar", -1));
   assert(bson_append_int32(b, "int32", -1, 1234));
   assert(bson_append_int64(b, "int64", -1, 4321));
   assert(bson_append_double(b, "double", -1, 123.4));
   assert(bson_append_undefined(b, "undefined", -1));
   assert(bson_append_null(b, "null", -1));
   assert(bson_append_oid(b, "oid", -1, &oid));
   assert(bson_append_bool(b, "true", -1, true));
   assert(bson_append_bool(b, "false", -1, false));
   assert(bson_append_time_t(b, "date", -1, time(NULL)));
   assert(bson_append_timestamp(b, "timestamp", -1, (uint32_t)time(NULL), 1234));
   assert(bson_append_regex(b, "regex", -1, "^abcd", "xi"));
   assert(bson_append_dbpointer(b, "dbpointer", -1, "mycollection", &oid));
   assert(bson_append_minkey(b, "minkey", -1));
   assert(bson_append_maxkey(b, "maxkey", -1));
   assert(bson_append_symbol(b, "symbol", -1, "var a = {};", -1));
   assert(bson_append_decimal128(b, "decimal128", -1, &decimal128));

   b2 = bson_new();
   assert(bson_append_int32(b2, "0", -1, 60));
   assert(bson_append_document(b, "document", -1, b2));
   assert(bson_append_array(b, "array", -1, b2));

   {
      const uint8_t binary[] = { 0, 1, 2, 3, 4 };
      assert(bson_append_binary(b, "binary", -1, BSON_SUBTYPE_BINARY,
                                binary, sizeof binary));
   }

   for (i = 0; i < 1000; i++) {
      str = bson_as_json(b, &len);
      bson_free(str);
   }

   bson_destroy(b);
   bson_destroy(b2);
}
Example #5
0
static void
test_bson_iter_mixed (void)
{
   bson_iter_t iter;
   bson_decimal128_t iter_value;
   bson_decimal128_t value;
   bson_t *b;
   bson_t *b2;

   b = bson_new();
   b2 = bson_new();

   value.high = 0;
   value.low = 1;

   assert(bson_append_utf8(b2, "foo", -1, "bar", -1));
   assert(bson_append_code(b, "0", -1, "var a = {};"));
   assert(bson_append_code_with_scope(b, "1", -1, "var b = {};", b2));
   assert(bson_append_int32(b, "2", -1, 1234));
   assert(bson_append_int64(b, "3", -1, 4567));
   assert(bson_append_time_t(b, "4", -1, 123456));
   assert(bson_append_decimal128(b, "5", -1, &value));
   assert(bson_iter_init(&iter, b));
   assert(bson_iter_next(&iter));
   assert(BSON_ITER_HOLDS_CODE(&iter));
   assert(bson_iter_next(&iter));
   assert(BSON_ITER_HOLDS_CODEWSCOPE(&iter));
   assert(bson_iter_next(&iter));
   assert(BSON_ITER_HOLDS_INT32(&iter));
   assert(bson_iter_next(&iter));
   assert(BSON_ITER_HOLDS_INT64(&iter));
   assert(bson_iter_next(&iter));
   assert(BSON_ITER_HOLDS_DATE_TIME(&iter));
   assert(bson_iter_next(&iter));
   assert(BSON_ITER_HOLDS_DECIMAL128(&iter));
   assert(!bson_iter_next(&iter));
   assert(bson_iter_init_find(&iter, b, "3"));
   assert(!strcmp(bson_iter_key(&iter), "3"));
   assert(bson_iter_int64(&iter) == 4567);
   assert(bson_iter_next(&iter));
   assert(BSON_ITER_HOLDS_DATE_TIME(&iter));
   assert(bson_iter_time_t(&iter) == 123456);
   assert(bson_iter_date_time(&iter) == 123456000);
   assert(bson_iter_next(&iter));
   /* This test uses memcmp because libbson lacks decimal128 comparison. */
   bson_iter_decimal128(&iter, &iter_value);
   assert(memcmp(&iter_value, &value, sizeof(value)) == 0);
   assert(!bson_iter_next(&iter));
   bson_destroy(b);
   bson_destroy(b2);
}
Example #6
0
static void
test_bson_append_time_t (void)
{
   bson_t *b;
   bson_t *b2;
   time_t t;

   t = 1234567890;

   b = bson_new();
   assert(bson_append_time_t(b, "time_t", -1, t));
   b2 = get_bson("test26.bson");
   assert_bson_equal(b, b2);
   bson_destroy(b);
   bson_destroy(b2);
}
int
main (int   argc,
      char *argv[])
{
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   mongoc_cursor_t *cursor;
   bson_error_t error;
   const bson_t *doc;
   const char *uristr = "mongodb://*****:*****@localhost/?authMechanism=PLAIN&authSource=$external";
   const char *database_name = "test";
   const char *collection_name = "query1";
   const char *user_role = "ro";

   if (argc == 2 && !strcmp("--help",argv[1])) {
     printf ("Usage: [uri [database [collection [ro|rw]]]]\n");
     return EXIT_FAILURE;
   }

   if (argc > 1) {
      uristr = argv [1];
   }

   if (argc > 2) {
      database_name = argv [2];
   }

   if (argc > 3) {
      collection_name = argv [3];
   }

   if (argc > 4) {
      user_role = argv [4];
   }

   mongoc_init ();

   client = mongoc_client_new (uristr);
   collection = mongoc_client_get_collection (client, database_name, collection_name);

   if (!client) {
      fprintf (stderr, "Failed to parse URI.\n");
      return EXIT_FAILURE;
   }

   // write

   if (!strcasecmp(user_role,"rw")) {

      bson_t *rwbson;
      bson_error_t rwerror;

      rwbson = bson_new();
      time_t now = time(NULL);
      bson_append_utf8(rwbson,"db",-1,database_name,-1);
      bson_append_time_t(rwbson,"date",-1,now);
      mongoc_client_get_database(client, database_name);
      bool ret = mongoc_collection_insert(collection, MONGOC_INSERT_NONE, rwbson, NULL,
                                                                     &rwerror);

      bson_destroy(rwbson);

      if (!ret)
          return EXIT_FAILURE;

   }

   // read
   bson_t roquery;
   bson_init (&roquery);
   char *str;

#if 0
   eson_append_utf8 (&roquery, "hello", -1, "world", -1);
#endif

   cursor = mongoc_collection_find (collection,
                                    MONGOC_QUERY_NONE,
                                    0,
                                    0,
                                    0,
                                    &roquery,
                                    NULL,  /* Fields, NULL for all. */
                                    NULL); /* Read Prefs, NULL for default */
   while (mongoc_cursor_next (cursor, &doc)) {
      str = bson_as_json (doc, NULL);
      fprintf (stdout, "%s\n", str);
      bson_free (str);
   }

   if (mongoc_cursor_error (cursor, &error)) {
      fprintf (stderr, "Cursor Failure: %s\n", error.message);
      return EXIT_FAILURE;
   }

   bson_destroy (&roquery);

  // close server connection

   mongoc_cursor_destroy (cursor);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);

   mongoc_cleanup ();

   return EXIT_SUCCESS;
}
Example #8
0
/*
 * Add key-op-value to a bson filter document
 */
int db_mongodb_bson_filter_add(bson_t *doc, const db_key_t* _k, const db_op_t* _op,
		const db_val_t* _v, int idx)
{
	bson_t mdoc;
	db_key_t tkey;
	const db_val_t *tval;
	int vtype;
	str ocmp;

	tkey = _k[idx];
	tval = _v + idx;
	vtype = VAL_TYPE(tval);

	/* OP_EQ is handled separately */
	if(!strcmp(_op[idx], OP_LT)) {
		ocmp.s = "$lt";
		ocmp.len = 3;
	} else if(!strcmp(_op[idx], OP_LEQ)) {
		ocmp.s = "$lte";
		ocmp.len = 4;
	} else if(!strcmp(_op[idx], OP_GT)) {
		ocmp.s = "$gt";
		ocmp.len = 3;
	} else if(!strcmp(_op[idx], OP_GEQ)) {
		ocmp.s = "$gte";
		ocmp.len = 4;
	} else if(!strcmp(_op[idx], OP_NEQ)
			|| !strcmp(_op[idx], "!=")) {
		ocmp.s = "$ne";
		ocmp.len = 3;
	} else {
		LM_ERR("unsuported match operator: %s\n", _op[idx]);
		goto error;
	}

	if(!bson_append_document_begin(doc, tkey->s, tkey->len, &mdoc)) {
		LM_ERR("failed to append start to bson doc %.*s %s ... [%d]\n",
					tkey->len, tkey->s, ocmp.s, idx);
		goto error;
	}

	if(VAL_NULL(tval)) {
		if(!bson_append_null(&mdoc, ocmp.s, ocmp.len)) {
			LM_ERR("failed to append null to bson doc %.*s %s null [%d]\n",
					tkey->len, tkey->s, ocmp.s, idx);
			goto error;
		}
		goto done;
	}
	switch(vtype) {
		case DB1_INT:
			if(!bson_append_int32(&mdoc, ocmp.s, ocmp.len,
						VAL_INT(tval))) {
				LM_ERR("failed to append int to bson doc %.*s %s %d [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_INT(tval), idx);
				goto error;
			}
			break;

		case DB1_BIGINT:
			if(!bson_append_int64(&mdoc, ocmp.s, ocmp.len,
						VAL_BIGINT(tval ))) {
				LM_ERR("failed to append bigint to bson doc %.*s %s %lld [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_BIGINT(tval), idx);
				goto error;
			}
			return -1;

		case DB1_DOUBLE:
			if(!bson_append_double(&mdoc, ocmp.s, ocmp.len,
						VAL_DOUBLE(tval))) {
				LM_ERR("failed to append double to bson doc %.*s %s %f [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_DOUBLE(tval), idx);
				goto error;
			}
			break;

		case DB1_STRING:
			if(!bson_append_utf8(&mdoc, ocmp.s, ocmp.len,
						VAL_STRING(tval), strlen(VAL_STRING(tval))) ) {
				LM_ERR("failed to append string to bson doc %.*s %s %s [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_STRING(tval), idx);
				goto error;
			}
			break;

		case DB1_STR:

			if(!bson_append_utf8(&mdoc, ocmp.s, ocmp.len,
						VAL_STR(tval).s, VAL_STR(tval).len) ) {
				LM_ERR("failed to append str to bson doc %.*s %s %.*s [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_STR(tval).len, VAL_STR(tval).s, idx);
				goto error;
			}
			break;

		case DB1_DATETIME:
			if(!bson_append_time_t(&mdoc, ocmp.s, ocmp.len,
						VAL_TIME(tval))) {
				LM_ERR("failed to append time to bson doc %.*s %s %ld [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_TIME(tval), idx);
				goto error;
			}
			break;

		case DB1_BLOB:
			if(!bson_append_binary(&mdoc, ocmp.s, ocmp.len,
						BSON_SUBTYPE_BINARY,
						(const uint8_t *)VAL_BLOB(tval).s, VAL_BLOB(tval).len) ) {
				LM_ERR("failed to append blob to bson doc %.*s %s [bin] [%d]\n",
						tkey->len, tkey->s, ocmp.s, idx);
				goto error;
			}
			break;

		case DB1_BITMAP:
			if(!bson_append_int32(&mdoc, ocmp.s, ocmp.len,
						VAL_INT(tval))) {
				LM_ERR("failed to append bitmap to bson doc %.*s %s %d [%d]\n",
						tkey->len, tkey->s, ocmp.s, VAL_INT(tval), idx);
				goto error;
			}
			break;

		default:
			LM_ERR("val type [%d] not supported\n", vtype);
			goto error;
	}

done:
	if(!bson_append_document_end(doc, &mdoc)) {
		LM_ERR("failed to append end to bson doc %.*s %s ... [%d]\n",
					tkey->len, tkey->s, ocmp.s, idx);
		goto error;
	}
	return 0;
error:
	return -1;
}
Example #9
0
/*
 * Add key-value to a bson document
 */
int db_mongodb_bson_add(bson_t *doc, const db_key_t _k, const db_val_t *_v, int idx)
{
	int vtype;

	vtype = VAL_TYPE(_v);
	if(VAL_NULL(_v)) {
		if(!bson_append_null(doc, _k->s, _k->len)) {
			LM_ERR("failed to append int to bson doc %.*s = %d [%d]\n",
					_k->len, _k->s, VAL_INT(_v), idx);
			goto error;
		}
		goto done;
	}
	switch(vtype) {
		case DB1_INT:
			if(!bson_append_int32(doc, _k->s, _k->len,
						VAL_INT(_v))) {
				LM_ERR("failed to append int to bson doc %.*s = %d [%d]\n",
						_k->len, _k->s, VAL_INT(_v), idx);
				goto error;
			}
			break;

		case DB1_BIGINT:
			if(!bson_append_int64(doc, _k->s, _k->len,
						VAL_BIGINT(_v ))) {
				LM_ERR("failed to append bigint to bson doc %.*s = %lld [%d]\n",
						_k->len, _k->s, VAL_BIGINT(_v), idx);
				goto error;
			}
			return -1;

		case DB1_DOUBLE:
			if(!bson_append_double(doc, _k->s, _k->len,
						VAL_DOUBLE(_v))) {
				LM_ERR("failed to append double to bson doc %.*s = %f [%d]\n",
						_k->len, _k->s, VAL_DOUBLE(_v), idx);
				goto error;
			}
			break;

		case DB1_STRING:
			if(!bson_append_utf8(doc, _k->s, _k->len,
						VAL_STRING(_v), strlen(VAL_STRING(_v))) ) {
				LM_ERR("failed to append string to bson doc %.*s = %s [%d]\n",
						_k->len, _k->s, VAL_STRING(_v), idx);
				goto error;
			}
			break;

		case DB1_STR:

			if(!bson_append_utf8(doc, _k->s, _k->len,
						VAL_STR(_v).s, VAL_STR(_v).len) ) {
				LM_ERR("failed to append str to bson doc %.*s = %.*s [%d]\n",
						_k->len, _k->s, VAL_STR(_v).len, VAL_STR(_v).s, idx);
				goto error;
			}
			break;

		case DB1_DATETIME:
			if(!bson_append_time_t(doc, _k->s, _k->len,
						VAL_TIME(_v))) {
				LM_ERR("failed to append time to bson doc %.*s = %ld [%d]\n",
						_k->len, _k->s, VAL_TIME(_v), idx);
				goto error;
			}
			break;

		case DB1_BLOB:
			if(!bson_append_binary(doc, _k->s, _k->len,
						BSON_SUBTYPE_BINARY,
						(const uint8_t *)VAL_BLOB(_v).s, VAL_BLOB(_v).len) ) {
				LM_ERR("failed to append blob to bson doc %.*s = [bin] [%d]\n",
						_k->len, _k->s, idx);
				goto error;
			}
			break;

		case DB1_BITMAP:
			if(!bson_append_int32(doc, _k->s, _k->len,
						VAL_INT(_v))) {
				LM_ERR("failed to append bitmap to bson doc %.*s = %d [%d]\n",
						_k->len, _k->s, VAL_INT(_v), idx);
				goto error;
			}
			break;

		default:
			LM_ERR("val type [%d] not supported\n", vtype);
			return -1;
	}

done:
	return 0;
error:
	return -1;
}
static void
ngx_wirte_tracking_into_mongodb(ngx_http_request_t *r,
                                ngx_http_vesb_aio_log_main_conf_t *valcf,ngx_http_vesb_aio_log_loc_conf_t *vallcf,int timeuse)
{
    mongo                     conn[1];
    char                      *conn_str;
    int                       port,status,insertstatus;
    time_t                    timenow;
    ngx_list_part_t 		      *part = &r->headers_in.headers.part;
    ngx_table_elt_t 		      *header = part->elts;
    ngx_uint_t				        i;

    if(r->headers_out.status == NGX_HTTP_OK)
    {
        conn_str = (char *)valcf->mongodb_conn_str.data;
        port = (int)valcf->mongodb_conn_port;
        status = mongo_client( conn, conn_str, port );
        if( status == MONGO_OK ) {
            mongo_set_op_timeout( conn, 10000 );//time oust 10000 ms
            time ( &timenow );
            bson b[1];
            bson_init( b );
            bson_append_new_oid( b, "_id" );

            if( r->headers_in.x_forwarded_for == NULL )
            {
                bson_append_string_n( b, "realclientip" , (char *)r->connection->addr_text.data, r->connection->addr_text.len);
            }
            else
            {
                bson_append_string_n( b, "realclientip" , (char *)r->headers_in.x_forwarded_for->value.data,r->headers_in.x_forwarded_for->value.len);
            }

            bson_append_int( b,"statuscode",r->headers_out.status);
            bson_append_int( b,"usetime",timeuse);
            bson_append_long( b,"requestsize",r->request_length);
            bson_append_long( b,"responsesize",r->headers_out.content_length_n);
            bson_append_time_t( b,"invoketime",timenow );


            if(vallcf->app_name.data != NULL)
            {
                bson_append_string_n( b,"appname",(char *)vallcf->app_name.data,vallcf->app_name.len);
            }
            else
            {
                bson_append_string( b,"appname","undefine");
            }

            /*get method name*/
            for(i=0;/* void */; ++i)
            {
                if(i >= part->nelts)
                {
                    if(part->next == NULL)
                    {
                        break;
                    }

                    part = part->next;
                    header = part->elts;
                    i=0;
                }

                if(header[i].hash == 0)
                {
                    continue;
                }

                if(ngx_strstr(header[i].key.data,"SOAPAction") != NULL)
                {
                    bson_append_string_n( b,"SOAPAction",(char *)header[i].value.data,header[i].value.len);
                }
                else if(ngx_strstr(header[i].key.data,"Content-Type") != NULL)
                {
                    bson_append_string_n( b,"Content-Type",(char *)header[i].value.data,header[i].value.len);
                }
            }


            bson_finish( b );
            insertstatus = mongo_insert( conn,"vesb.tracking", b , NULL );

            if( insertstatus != MONGO_OK ) {
                ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "insert tracking log in mongodb is failed!(error:%d)",conn[0].err);
            }
            bson_destroy( b );
        }
        else
        {
            ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "mongodb is unconnection!(error:%d)",status);
        }

        mongo_destroy( conn );

    }
}
Example #11
0
static bcon_error_t bson_bcon_key_value(bson *b, const char *key, const char *typespec, const bcon bci) {
    bcon_error_t ret = BCON_OK;
    bson_oid_t oid;
    char ptype = typespec ? typespec[1] : '_';
    char utype = typespec ? typespec[2] : '_';
    switch (ptype) {
    case '_': /* kv(b, key, utype, bci) */
        switch (utype) {
        case '_': /* fall through */
        case 's': bson_append_string( b, key, bci.s ); break; /* common case */
        case 'f': bson_append_double( b, key, bci.f ); break;
        case 'D':
            bson_append_start_object( b, key );
            ret = bson_append_bcon( b, bci.D );
            bson_append_finish_object( b );
            break;
        case 'A':
            bson_append_start_array( b, key );
            ret = bson_append_bcon_array( b, bci.A );
            bson_append_finish_array( b );
            break;
        case 'o': if (*bci.o == '\0') bson_oid_gen( &oid ); else bson_oid_from_string( &oid, bci.o ); bson_append_oid( b, key, &oid ); break;
        case 'b': bson_append_bool( b, key, bci.b ); break;
        case 't': bson_append_time_t( b, key, bci.t ); break;
        case 'v': bson_append_null( b, key ); break; /* void */
        case 'x': bson_append_symbol( b, key, bci.x ); break;
        case 'i': bson_append_int( b, key, bci.i ); break;
        case 'l': bson_append_long( b, key, bci.l ); break;
        default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break;
        }
        break;
    case 'R': /* krv(b, key, utype, bci) */
        switch (utype) {
        case 'f': bson_append_double( b, key, *bci.Rf ); break;
        case 's': bson_append_string( b, key, bci.Rs ); break;
        case 'D':
            bson_append_start_object( b, key );
            ret = bson_append_bcon( b, bci.RD );
            bson_append_finish_object( b );
            break;
        case 'A':
            bson_append_start_array( b, key );
            ret = bson_append_bcon_array( b, bci.RA );
            bson_append_finish_array( b );
            break;
        case 'o': if (*bci.o == '\0') bson_oid_gen( &oid ); else bson_oid_from_string( &oid, bci.o ); bson_append_oid( b, key, &oid ); break;
        case 'b': bson_append_bool( b, key, *bci.Rb ); break;
        case 't': bson_append_time_t( b, key, *bci.Rt ); break;
        case 'x': bson_append_symbol( b, key, bci.Rx ); break;
        case 'i': bson_append_int( b, key, *bci.Ri ); break;
        case 'l': bson_append_long( b, key, *bci.Rl ); break;
        default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break;
        }
        break;
    case 'P': /* kpv(b, key, utype, bci) */
        if (*bci.Pv != 0) {
            switch (utype) {
            case 'f': bson_append_double( b, key, **bci.Pf ); break;
            case 's': bson_append_string( b, key, *bci.Ps ); break;
            case 'D':
                bson_append_start_object( b, key );
                ret = bson_append_bcon( b, *bci.PD );
                bson_append_finish_object( b );
                break;
            case 'A':
                bson_append_start_array( b, key );
                ret = bson_append_bcon_array( b, *bci.PA );
                bson_append_finish_array( b );
                break;
            case 'o': if (**bci.Po == '\0') bson_oid_gen( &oid );
                else bson_oid_from_string( &oid, *bci.Po );
                bson_append_oid( b, key, &oid );
                break;
            case 'b': bson_append_bool( b, key, **bci.Pb ); break;
            case 't': bson_append_time_t( b, key, **bci.Pt ); break;
            case 'x': if (*bci.Px != 0) bson_append_symbol( b, key, *bci.Px ); break;
            case 'i': bson_append_int( b, key, **bci.Pi ); break;
            case 'l': bson_append_long( b, key, **bci.Pl ); break;
            default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break;
            }
        }
        break;
    default:
        printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED);
        break;
    }
    return ret;
}
Example #12
0
int mongo_write(const char *path, const char *buf, size_t size,
                off_t offset, struct fuse_file_info *fi)
{
    struct inode * e;
    int res;
    size_t reallen;
    int32_t realend = size, blk_offset = 0;
    const off_t write_end = size + offset;
    char * lock;
    bson doc, cond;
    mongo * conn = get_conn();
    uint8_t hash[20];
    time_t now = time(NULL);

    e = (struct inode*)fi->fh;
    if((res = get_cached_inode(path, e)) != 0)
        return res;

    if(e->mode & S_IFDIR)
        return -EISDIR;

    /* Uncomment this for incredibly slow length calculations.
    for(;realend >= 0 && buf[realend] == '\0'; realend--);
    realend++;
    for(blk_offset = 0; blk_offset < realend && buf[blk_offset] == 0; blk_offset++);
    blk_offset -= blk_offset > 0 ? 1 : 0;
    * The code below uses SSE4 instructions to find the first/last
    * zero bytes by doing 16-byte comparisons at a time. This should give
    * a ~16 speed boost on blocks with lots of zero bytes over the dumb
    * method above.
    */
    
    if(size >= 16) {
        __m128i zero = _mm_setzero_si128();
        lock = (char*)buf + size - 16;
        while(lock >= buf) {
            __m128i x = _mm_loadu_si128((__m128i*)lock);
            res = _mm_movemask_epi8(_mm_cmpeq_epi8(zero, x));
            if(res == 0xffff) {
                lock -= 16;
                continue;
            }
            realend = lock - buf + fls(res ^ 0xffff);
            break;
        }
        if(lock <= buf)
            realend = 0;

        lock = (char*)buf;
        while(lock - buf < realend) {
            __m128i x = _mm_loadu_si128((__m128i*)lock);
            res = _mm_movemask_epi8(_mm_cmpeq_epi8(zero, x));
            if(res == 0xffff) {
                lock += 16;
                continue;
            }
            blk_offset = lock - buf + ffs(res ^ 0xffff) - 1;
            break;
        }
    }

    reallen = realend - blk_offset;
    if(reallen == 0) {
        pthread_mutex_lock(&e->wr_lock);
        res = insert_empty(&e->wr_extent, offset, size);
        goto end;
    }

#ifdef __APPLE__
    CC_SHA1(buf, size, hash);
#else
    SHA1(buf, size, hash);
#endif

    bson_init(&cond);
    bson_append_binary(&cond, "_id", 0, (char*)hash, sizeof(hash));
    bson_finish(&cond);

    bson_init(&doc);
    bson_append_start_object(&doc, "$setOnInsert");
    char * comp_out = get_compress_buf();
    size_t comp_size = snappy_max_compressed_length(reallen);
    if((res = snappy_compress(buf + blk_offset, reallen,
        comp_out, &comp_size)) != SNAPPY_OK) {
        fprintf(stderr, "Error compressing input: %d\n", res);
        return -EIO;
    }
    bson_append_binary(&doc, "data", 0, comp_out, comp_size);
    bson_append_int(&doc, "offset", blk_offset);
    bson_append_int(&doc, "size", size);
    bson_append_time_t(&doc, "created", now);
    bson_append_finish_object(&doc);
    bson_finish(&doc);

    res = mongo_update(conn, blocks_name, &cond, &doc,
        MONGO_UPDATE_UPSERT, NULL);
    bson_destroy(&doc);
    bson_destroy(&cond);

    if(res != MONGO_OK) {
        fprintf(stderr, "Error committing block %s\n", conn->lasterrstr);
        return -EIO;
    }

    pthread_mutex_lock(&e->wr_lock);
    res = insert_hash(&e->wr_extent, offset, size, hash);

end:
    if(write_end > e->size)
        e->size = write_end;

    if(now - e->wr_age > 3) {
        res = serialize_extent(e, e->wr_extent);
        if(res != 0) {
            pthread_mutex_unlock(&e->wr_lock);
            return res;    
        }
        e->wr_age = now;
    }
    pthread_mutex_unlock(&e->wr_lock);
    if(res != 0)
        return res;

    res = update_filesize(e, write_end);

    if(res != 0)
        return res;
    return size;
}