From 951f15990194d637e013bc4e70ed7089a1a62bc4 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick <daniel.swarbrick@gmail.com> Date: Thu, 10 May 2012 11:03:04 +0200 Subject: [PATCH] update mongo-c-driver to 0.5.2 --- .../event_handlers/mod_cdr_mongodb/Makefile | 6 +- .../mod_cdr_mongodb/driver/HISTORY.md | 30 + .../mod_cdr_mongodb/driver/README.md | 4 +- .../mod_cdr_mongodb/driver/SConstruct | 178 ------ .../mod_cdr_mongodb/driver/src/bson.c | 308 ++++++---- .../mod_cdr_mongodb/driver/src/bson.h | 241 +++++--- .../mod_cdr_mongodb/driver/src/encoding.c | 2 +- .../mod_cdr_mongodb/driver/src/encoding.h | 6 +- .../mod_cdr_mongodb/driver/src/env.h | 39 ++ .../mod_cdr_mongodb/driver/src/env_posix.c | 165 +++++ .../mod_cdr_mongodb/driver/src/env_standard.c | 168 +++++ .../mod_cdr_mongodb/driver/src/env_win32.c | 183 ++++++ .../mod_cdr_mongodb/driver/src/gridfs.c | 115 ++-- .../mod_cdr_mongodb/driver/src/gridfs.h | 64 +- .../mod_cdr_mongodb/driver/src/md5.c | 6 +- .../mod_cdr_mongodb/driver/src/md5.h | 19 +- .../mod_cdr_mongodb/driver/src/mongo.c | 576 +++++++++++++----- .../mod_cdr_mongodb/driver/src/mongo.h | 191 ++++-- .../mod_cdr_mongodb/driver/src/net.c | 98 --- .../mod_cdr_mongodb/driver/src/net.h | 57 -- .../mod_cdr_mongodb/driver/src/numbers.c | 2 +- .../mod_cdr_mongodb/driver/src/platform.h | 94 --- .../driver/src/platform/linux/net.c | 183 ------ .../driver/src/platform/linux/net.h | 51 -- 24 files changed, 1598 insertions(+), 1188 deletions(-) delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/SConstruct create mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/env.h create mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c create mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_standard.c create mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_win32.c delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.c delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.h delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform.h delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.c delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.h diff --git a/src/mod/event_handlers/mod_cdr_mongodb/Makefile b/src/mod/event_handlers/mod_cdr_mongodb/Makefile index b9e04b983d..6a412a0f66 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/Makefile +++ b/src/mod/event_handlers/mod_cdr_mongodb/Makefile @@ -2,8 +2,8 @@ include ../../../../build/modmake.rules MONGODB_DRIVER=./driver/src LOCAL_CFLAGS=-I$(MONGODB_DRIVER) -LOCAL_OBJS=$(MONGODB_DRIVER)/md5.o \ - $(MONGODB_DRIVER)/mongo.o $(MONGODB_DRIVER)/net.o \ - $(MONGODB_DRIVER)/bson.o $(MONGODB_DRIVER)/numbers.o $(MONGODB_DRIVER)/encoding.o \ +LOCAL_OBJS=$(MONGODB_DRIVER)/encoding.o $(MONGODB_DRIVER)/env_posix.o \ + $(MONGODB_DRIVER)/bson.o $(MONGODB_DRIVER)/md5.o \ + $(MONGODB_DRIVER)/mongo.o $(MONGODB_DRIVER)/numbers.o local_depend: $(LOCAL_OBJS) diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/HISTORY.md b/src/mod/event_handlers/mod_cdr_mongodb/driver/HISTORY.md index f3f0fab21d..1659192909 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/HISTORY.md +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/HISTORY.md @@ -1,5 +1,35 @@ # MongoDB C Driver History +## 0.5.2 +2012-5-4 + +* Validate collection and database names on insert. +* Validate insert limits using max BSON size. +* Support getaddrinfo and SO_RCVTIMEO and SO_SNDTIMEO on Windows. +* Store errno/WSAGetLastError() on errors. +* Various bug fixes and refactorings. +* Update error reporting docs. + +## 0.5.1 + +* Env for POSIX, WIN32, and standard C. +* Various bug fixes. + +## 0.5 +2012-3-31 + +* Separate cursor-specific errors into their own enum: mongo_cursor_error_t. +* Catch $err return on bad queries and store the result in conn->getlasterrorcode + and conn->getlasterrstr. +* On queries that return $err, set cursor->err to MONGO_CURSOR_QUERY_FAIL. +* When passing bad BSON to a cursor object, set cursor->err to MONGO_CURSOR_BSON_ERROR, + and store the specific BSON error on the conn->err field. +* Remove bson_copy_basic(). +* bson_copy() will copy finished bson objects only. +* bson_copy() returns BSON_OK on success and BSON_ERROR on failure. +* Added a Makefile for easy compile and install on Linux and OS X. +* Replica set connect fixes. + ## 0.4 THIS RELEASE INCLUDES NUMEROUS BACKWARD-BREAKING CHANGES. diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/README.md b/src/mod/event_handlers/mod_cdr_mongodb/driver/README.md index 1afe39e69c..d8c7526683 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/README.md +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/README.md @@ -12,9 +12,9 @@ Until the 1.0 release, this driver should be considered alpha. Keep in mind that # Building First check out the version you want to build. *Always build from a particular tag, since HEAD may be -a work in progress.* For example, to build version 0.4, run: +a work in progress.* For example, to build version 0.5.2, run: - git checkout v0.4 + git checkout v0.5.2 You can then build the driver with scons: diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/SConstruct b/src/mod/event_handlers/mod_cdr_mongodb/driver/SConstruct deleted file mode 100644 index d3be2d89a6..0000000000 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/SConstruct +++ /dev/null @@ -1,178 +0,0 @@ -# -*- mode: python; -*- - -VERSION = "0.4" - -# --- options ---- -AddOption('--test-server', - dest='test_server', - default='127.0.0.1', - type='string', - nargs=1, - action='store', - help='IP address of server to use for testing') - -AddOption('--seed-start-port', - dest='seed_start_port', - default=30000, - type='int', - nargs=1, - action='store', - help='IP address of server to use for testing') - -AddOption('--c99', - dest='use_c99', - default=False, - action='store_true', - help='Compile with c99 (recommended for gcc)') - -AddOption('--d', - dest='optimize', - default=True, - action='store_false', - help='disable optimizations') - -AddOption('--use-platform', - dest='compile_platform', - default='GENERIC', - type='string', - nargs=1, - action='store', - help='Compile for a specific platform to take advantage ' - ' of particular system features. For the moment, this include timeouts only.' - ' Current options include LINUX, ' - ' GENERIC, and CUSTOM. If you specific CUSTOM, you must place a' - ' system-specific implementation of net.h and net.c in src/platform/custom/') - -import os, sys - -env = Environment( ENV=os.environ ) - -# ---- Docs ---- -def build_docs(env, target, source): - buildscript_path = os.path.join(os.path.abspath("docs")) - sys.path.insert(0, buildscript_path) - import buildscripts - from buildscripts import docs - docs.main() - -env.Alias("docs", [], [build_docs]) -env.AlwaysBuild("docs") - -# ---- Platforms ---- -PLATFORM_TEST_DIR = None -if "LINUX" == GetOption('compile_platform'): - env.Append( CPPFLAGS=" -D_MONGO_USE_LINUX_SYSTEM" ) - NET_LIB = "src/platform/linux/net.c" - PLATFORM_TEST_DIR = "test/platform/linux/" - PLATFORM_TESTS = [ "timeouts" ] -elif "CUSTOM" == GetOption('compile_platform'): - env.Append( CPPFLAGS=" -D_MONGO_USE_CUSTOM_SYSTEM" ) - NET_LIB = "src/platform/custom/net.c" -else: - NET_LIB = "src/net.c" - -# ---- Libraries ---- -if os.sys.platform in ["darwin", "linux2"]: - env.Append( CPPFLAGS=" -pedantic -Wall -ggdb -DMONGO_HAVE_STDINT" ) - env.Append( CPPPATH=["/opt/local/include/"] ) - env.Append( LIBPATH=["/opt/local/lib/"] ) - - if GetOption('use_c99'): - env.Append( CFLAGS=" -std=c99 " ) - env.Append( CXXDEFINES="MONGO_HAVE_STDINT" ) - else: - env.Append( CFLAGS=" -ansi " ) - - if GetOption('optimize'): - env.Append( CPPFLAGS=" -O3 " ) - # -O3 benchmarks *significantly* faster than -O2 when disabling networking -elif 'win32' == os.sys.platform: - env.Append( LIBS='ws2_32' ) - -#we shouldn't need these options in c99 mode -if not GetOption('use_c99'): - conf = Configure(env) - - if not conf.CheckType('int64_t'): - if conf.CheckType('int64_t', '#include <stdint.h>\n'): - conf.env.Append( CPPDEFINES="MONGO_HAVE_STDINT" ) - elif conf.CheckType('int64_t', '#include <unistd.h>\n'): - conf.env.Append( CPPDEFINES="MONGO_HAVE_UNISTD" ) - elif conf.CheckType('__int64'): - conf.env.Append( CPPDEFINES="MONGO_USE__INT64" ) - elif conf.CheckType('long long int'): - conf.env.Append( CPPDEFINES="MONGO_USE_LONG_LONG_INT" ) - else: - print "*** what is your 64 bit int type? ****" - Exit(1) - - env = conf.Finish() - -have_libjson = False -conf = Configure(env) -if conf.CheckLib('json'): - have_libjson = True -env = conf.Finish() - -if sys.byteorder == 'big': - env.Append( CPPDEFINES="MONGO_BIG_ENDIAN" ) - -env.Append( CPPPATH=["src/"] ) - -coreFiles = ["src/md5.c" ] -mFiles = [ "src/mongo.c", NET_LIB, "src/gridfs.c"] -bFiles = [ "src/bson.c", "src/numbers.c", "src/encoding.c"] -mLibFiles = coreFiles + mFiles + bFiles -bLibFiles = coreFiles + bFiles -m = env.Library( "mongoc" , mLibFiles ) -b = env.Library( "bson" , bLibFiles ) -env.Default( env.Alias( "lib" , [ m[0] , b[0] ] ) ) - -if os.sys.platform == "linux2": - env.Append( SHLINKFLAGS="-shared -Wl,-soname,libmongoc.so." + VERSION ) - env.Append( SHLINKFLAGS = "-shared -Wl,-soname,libbson.so." + VERSION ) - -dynm = env.SharedLibrary( "mongoc" , mLibFiles ) -dynb = env.SharedLibrary( "bson" , bLibFiles ) -env.Default( env.Alias( "sharedlib" , [ dynm[0] , dynb[0] ] ) ) - - - -# ---- Benchmarking ---- -benchmarkEnv = env.Clone() -benchmarkEnv.Append( CPPDEFINES=[('TEST_SERVER', r'\"%s\"'%GetOption('test_server')), -('SEED_START_PORT', r'%d'%GetOption('seed_start_port'))] ) -benchmarkEnv.Append( LIBS=[m, b] ) -benchmarkEnv.Prepend( LIBPATH=["."] ) -benchmarkEnv.Program( "benchmark" , [ "test/benchmark.c"] ) - -# ---- Tests ---- -testEnv = benchmarkEnv.Clone() -testCoreFiles = [ ] - -def run_tests( root, tests ): - for name in tests: - filename = "%s/%s.c" % (root, name) - exe = "test_" + name - test = testEnv.Program( exe , testCoreFiles + [filename] ) - test_alias = testEnv.Alias('test', [test], test[0].abspath + ' 2> ' + os.path.devnull) - AlwaysBuild(test_alias) - -tests = Split("sizes resize endian_swap bson bson_subobject simple update errors " -"count_delete auth gridfs validate examples helpers oid functions cursors replica_set") - -# Run standard tests -run_tests("test", tests) - -# Run platform tests -if not PLATFORM_TEST_DIR is None: - run_tests( PLATFORM_TEST_DIR, PLATFORM_TESTS ) - -if have_libjson: - tests.append('json') - testEnv.Append( LIBS=["json"] ) - -# special case for cpptest -test = testEnv.Program( 'test_cpp' , testCoreFiles + ['test/cpptest.cpp'] ) -test_alias = testEnv.Alias('test', [test], test[0].abspath + ' 2> '+ os.path.devnull) -AlwaysBuild(test_alias) diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.c index 349f42284c..26d17d8696 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.c @@ -33,7 +33,11 @@ static const int zero = 0; void *( *bson_malloc_func )( size_t ) = malloc; void *( *bson_realloc_func )( void *, size_t ) = realloc; void ( *bson_free )( void * ) = free; +#ifdef R_SAFETY_NET +bson_printf_func bson_printf; +#else bson_printf_func bson_printf = printf; +#endif bson_fprintf_func bson_fprintf = fprintf; bson_sprintf_func bson_sprintf = sprintf; @@ -48,33 +52,32 @@ static int ( *oid_inc_func )( void ) = NULL; READING ------------------------------ */ -bson *bson_empty( bson *obj ) { +MONGO_EXPORT bson* bson_create() { + return (bson*)bson_malloc(sizeof(bson)); +} + +MONGO_EXPORT void bson_dispose(bson* b) { + bson_free(b); +} + +MONGO_EXPORT bson *bson_empty( bson *obj ) { static char *data = "\005\0\0\0\0"; bson_init_data( obj, data ); obj->finished = 1; obj->err = 0; + obj->errstr = NULL; obj->stackPos = 0; return obj; } -void bson_copy_basic( bson *out, const bson *in ) { - if ( !out ) return; +MONGO_EXPORT int bson_copy( bson *out, const bson *in ) { + if ( !out ) return BSON_ERROR; + if ( !in->finished ) return BSON_ERROR; bson_init_size( out, bson_size( in ) ); memcpy( out->data, in->data, bson_size( in ) ); -} + out->finished = 1; -void bson_copy( bson *out, const bson *in ) { - int i; - - if ( !out ) return; - bson_copy_basic( out, in ); - out->cur = out->data + ( in->cur - in->data ); - out->dataSize = in->dataSize; - out->finished = in->finished; - out->stackPos = in->stackPos; - out->err = in->err; - for( i=0; i<out->stackPos; i++ ) - out->stack[i] = in->stack[i]; + return BSON_OK; } int bson_init_data( bson *b, char *data ) { @@ -82,6 +85,12 @@ int bson_init_data( bson *b, char *data ) { return BSON_OK; } +int bson_init_finished_data( bson *b, char *data ) { + bson_init_data( b, data ); + b->finished = 1; + return BSON_OK; +} + static void _bson_reset( bson *b ) { b->finished = 0; b->stackPos = 0; @@ -89,7 +98,7 @@ static void _bson_reset( bson *b ) { b->errstr = NULL; } -int bson_size( const bson *b ) { +MONGO_EXPORT int bson_size( const bson *b ) { int i; if ( ! b || ! b->data ) return 0; @@ -97,7 +106,12 @@ int bson_size( const bson *b ) { return i; } -const char *bson_data( bson *b ) { +MONGO_EXPORT int bson_buffer_size( const bson *b ) { + return (b->cur - b->data + 1); +} + + +MONGO_EXPORT const char *bson_data( const bson *b ) { return (const char *)b->data; } @@ -146,14 +160,14 @@ static char hexbyte( char hex ) { } } -void bson_oid_from_string( bson_oid_t *oid, const char *str ) { +MONGO_EXPORT void bson_oid_from_string( bson_oid_t *oid, const char *str ) { int i; for ( i=0; i<12; i++ ) { oid->bytes[i] = ( hexbyte( str[2*i] ) << 4 ) | hexbyte( str[2*i + 1] ); } } -void bson_oid_to_string( const bson_oid_t *oid, char *str ) { +MONGO_EXPORT void bson_oid_to_string( const bson_oid_t *oid, char *str ) { static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; int i; for ( i=0; i<12; i++ ) { @@ -163,15 +177,15 @@ void bson_oid_to_string( const bson_oid_t *oid, char *str ) { str[24] = '\0'; } -void bson_set_oid_fuzz( int ( *func )( void ) ) { +MONGO_EXPORT void bson_set_oid_fuzz( int ( *func )( void ) ) { oid_fuzz_func = func; } -void bson_set_oid_inc( int ( *func )( void ) ) { +MONGO_EXPORT void bson_set_oid_inc( int ( *func )( void ) ) { oid_inc_func = func; } -void bson_oid_gen( bson_oid_t *oid ) { +MONGO_EXPORT void bson_oid_gen( bson_oid_t *oid ) { static int incr = 0; static int fuzz = 0; int i; @@ -196,18 +210,18 @@ void bson_oid_gen( bson_oid_t *oid ) { bson_big_endian32( &oid->ints[2], &i ); } -time_t bson_oid_generated_time( bson_oid_t *oid ) { +MONGO_EXPORT time_t bson_oid_generated_time( bson_oid_t *oid ) { time_t out; bson_big_endian32( &out, &oid->ints[0] ); return out; } -void bson_print( bson *b ) { +MONGO_EXPORT void bson_print( const bson *b ) { bson_print_raw( b->data , 0 ); } -void bson_print_raw( const char *data , int depth ) { +MONGO_EXPORT void bson_print_raw( const char *data , int depth ) { bson_iterator i; const char *key; int temp; @@ -223,69 +237,69 @@ void bson_print_raw( const char *data , int depth ) { key = bson_iterator_key( &i ); for ( temp=0; temp<=depth; temp++ ) - printf( "\t" ); + bson_printf( "\t" ); bson_printf( "%s : %d \t " , key , t ); switch ( t ) { case BSON_DOUBLE: - printf( "%f" , bson_iterator_double( &i ) ); + bson_printf( "%f" , bson_iterator_double( &i ) ); break; case BSON_STRING: - printf( "%s" , bson_iterator_string( &i ) ); + bson_printf( "%s" , bson_iterator_string( &i ) ); break; case BSON_SYMBOL: - printf( "SYMBOL: %s" , bson_iterator_string( &i ) ); + bson_printf( "SYMBOL: %s" , bson_iterator_string( &i ) ); break; case BSON_OID: bson_oid_to_string( bson_iterator_oid( &i ), oidhex ); - printf( "%s" , oidhex ); + bson_printf( "%s" , oidhex ); break; case BSON_BOOL: - printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" ); + bson_printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" ); break; case BSON_DATE: - printf( "%ld" , ( long int )bson_iterator_date( &i ) ); + bson_printf( "%ld" , ( long int )bson_iterator_date( &i ) ); break; case BSON_BINDATA: - printf( "BSON_BINDATA" ); + bson_printf( "BSON_BINDATA" ); break; case BSON_UNDEFINED: - printf( "BSON_UNDEFINED" ); + bson_printf( "BSON_UNDEFINED" ); break; case BSON_NULL: - printf( "BSON_NULL" ); + bson_printf( "BSON_NULL" ); break; case BSON_REGEX: - printf( "BSON_REGEX: %s", bson_iterator_regex( &i ) ); + bson_printf( "BSON_REGEX: %s", bson_iterator_regex( &i ) ); break; case BSON_CODE: - printf( "BSON_CODE: %s", bson_iterator_code( &i ) ); + bson_printf( "BSON_CODE: %s", bson_iterator_code( &i ) ); break; case BSON_CODEWSCOPE: - printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) ); + bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) ); bson_init( &scope ); bson_iterator_code_scope( &i, &scope ); - printf( "\n\t SCOPE: " ); + bson_printf( "\n\t SCOPE: " ); bson_print( &scope ); break; case BSON_INT: - printf( "%d" , bson_iterator_int( &i ) ); + bson_printf( "%d" , bson_iterator_int( &i ) ); break; case BSON_LONG: - printf( "%lld" , ( long long int )bson_iterator_long( &i ) ); + bson_printf( "%lld" , ( uint64_t )bson_iterator_long( &i ) ); break; case BSON_TIMESTAMP: ts = bson_iterator_timestamp( &i ); - printf( "i: %d, t: %d", ts.i, ts.t ); + bson_printf( "i: %d, t: %d", ts.i, ts.t ); break; case BSON_OBJECT: case BSON_ARRAY: - printf( "\n" ); + bson_printf( "\n" ); bson_print_raw( bson_iterator_value( &i ) , depth + 1 ); break; default: bson_errprintf( "can't print type : %d\n" , t ); } - printf( "\n" ); + bson_printf( "\n" ); } } @@ -293,17 +307,25 @@ void bson_print_raw( const char *data , int depth ) { ITERATOR ------------------------------ */ -void bson_iterator_init( bson_iterator *i, const bson *b ) { +MONGO_EXPORT bson_iterator* bson_iterator_create() { + return (bson_iterator*)malloc(sizeof(bson_iterator*)); +} + +MONGO_EXPORT void bson_iterator_dispose(bson_iterator* i) { + free(i); +} + +MONGO_EXPORT void bson_iterator_init( bson_iterator *i, const bson *b ) { i->cur = b->data + 4; i->first = 1; } -void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ) { +MONGO_EXPORT void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ) { i->cur = buffer + 4; i->first = 1; } -bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) { +MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) { bson_iterator_init( it, (bson *)obj ); while( bson_iterator_next( it ) ) { if ( strcmp( name, bson_iterator_key( it ) ) == 0 ) @@ -312,11 +334,11 @@ bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) { return bson_iterator_type( it ); } -bson_bool_t bson_iterator_more( const bson_iterator *i ) { +MONGO_EXPORT bson_bool_t bson_iterator_more( const bson_iterator *i ) { return *( i->cur ); } -bson_type bson_iterator_next( bson_iterator *i ) { +MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i ) { int ds; if ( i->first ) { @@ -384,15 +406,15 @@ bson_type bson_iterator_next( bson_iterator *i ) { return ( bson_type )( *i->cur ); } -bson_type bson_iterator_type( const bson_iterator *i ) { +MONGO_EXPORT bson_type bson_iterator_type( const bson_iterator *i ) { return ( bson_type )i->cur[0]; } -const char *bson_iterator_key( const bson_iterator *i ) { +MONGO_EXPORT const char *bson_iterator_key( const bson_iterator *i ) { return i->cur + 1; } -const char *bson_iterator_value( const bson_iterator *i ) { +MONGO_EXPORT const char *bson_iterator_value( const bson_iterator *i ) { const char *t = i->cur + 1; t += strlen( t ) + 1; return t; @@ -422,11 +444,11 @@ bson_bool_t bson_iterator_bool_raw( const bson_iterator *i ) { return bson_iterator_value( i )[0]; } -bson_oid_t *bson_iterator_oid( const bson_iterator *i ) { +MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i ) { return ( bson_oid_t * )bson_iterator_value( i ); } -int bson_iterator_int( const bson_iterator *i ) { +MONGO_EXPORT int bson_iterator_int( const bson_iterator *i ) { switch ( bson_iterator_type( i ) ) { case BSON_INT: return bson_iterator_int_raw( i ); @@ -439,7 +461,7 @@ int bson_iterator_int( const bson_iterator *i ) { } } -double bson_iterator_double( const bson_iterator *i ) { +MONGO_EXPORT double bson_iterator_double( const bson_iterator *i ) { switch ( bson_iterator_type( i ) ) { case BSON_INT: return bson_iterator_int_raw( i ); @@ -452,7 +474,7 @@ double bson_iterator_double( const bson_iterator *i ) { } } -int64_t bson_iterator_long( const bson_iterator *i ) { +MONGO_EXPORT int64_t bson_iterator_long( const bson_iterator *i ) { switch ( bson_iterator_type( i ) ) { case BSON_INT: return bson_iterator_int_raw( i ); @@ -465,14 +487,29 @@ int64_t bson_iterator_long( const bson_iterator *i ) { } } -bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ) { +MONGO_EXPORT bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ) { bson_timestamp_t ts; bson_little_endian32( &( ts.i ), bson_iterator_value( i ) ); bson_little_endian32( &( ts.t ), bson_iterator_value( i ) + 4 ); return ts; } -bson_bool_t bson_iterator_bool( const bson_iterator *i ) { + +MONGO_EXPORT int bson_iterator_timestamp_time( const bson_iterator *i ) { + int time; + bson_little_endian32( &time, bson_iterator_value( i ) + 4 ); + return time; +} + + +MONGO_EXPORT int bson_iterator_timestamp_increment( const bson_iterator *i ) { + int increment; + bson_little_endian32( &increment, bson_iterator_value( i ) ); + return increment; +} + + +MONGO_EXPORT bson_bool_t bson_iterator_bool( const bson_iterator *i ) { switch ( bson_iterator_type( i ) ) { case BSON_BOOL: return bson_iterator_bool_raw( i ); @@ -490,15 +527,21 @@ bson_bool_t bson_iterator_bool( const bson_iterator *i ) { } } -const char *bson_iterator_string( const bson_iterator *i ) { - return bson_iterator_value( i ) + 4; +MONGO_EXPORT const char *bson_iterator_string( const bson_iterator *i ) { + switch ( bson_iterator_type( i ) ) { + case BSON_STRING: + case BSON_SYMBOL: + return bson_iterator_value( i ) + 4; + default: + return ""; + } } int bson_iterator_string_len( const bson_iterator *i ) { return bson_iterator_int_raw( i ); } -const char *bson_iterator_code( const bson_iterator *i ) { +MONGO_EXPORT const char *bson_iterator_code( const bson_iterator *i ) { switch ( bson_iterator_type( i ) ) { case BSON_STRING: case BSON_CODE: @@ -510,57 +553,59 @@ const char *bson_iterator_code( const bson_iterator *i ) { } } -void bson_iterator_code_scope( const bson_iterator *i, bson *scope ) { +MONGO_EXPORT void bson_iterator_code_scope( const bson_iterator *i, bson *scope ) { if ( bson_iterator_type( i ) == BSON_CODEWSCOPE ) { int code_len; bson_little_endian32( &code_len, bson_iterator_value( i )+4 ); bson_init_data( scope, ( void * )( bson_iterator_value( i )+8+code_len ) ); + _bson_reset( scope ); + scope->finished = 1; } else { bson_empty( scope ); } } -bson_date_t bson_iterator_date( const bson_iterator *i ) { +MONGO_EXPORT bson_date_t bson_iterator_date( const bson_iterator *i ) { return bson_iterator_long_raw( i ); } -time_t bson_iterator_time_t( const bson_iterator *i ) { +MONGO_EXPORT time_t bson_iterator_time_t( const bson_iterator *i ) { return bson_iterator_date( i ) / 1000; } -int bson_iterator_bin_len( const bson_iterator *i ) { +MONGO_EXPORT int bson_iterator_bin_len( const bson_iterator *i ) { return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD ) ? bson_iterator_int_raw( i ) - 4 : bson_iterator_int_raw( i ); } -char bson_iterator_bin_type( const bson_iterator *i ) { +MONGO_EXPORT char bson_iterator_bin_type( const bson_iterator *i ) { return bson_iterator_value( i )[4]; } -const char *bson_iterator_bin_data( const bson_iterator *i ) { +MONGO_EXPORT const char *bson_iterator_bin_data( const bson_iterator *i ) { return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD ) ? bson_iterator_value( i ) + 9 : bson_iterator_value( i ) + 5; } -const char *bson_iterator_regex( const bson_iterator *i ) { +MONGO_EXPORT const char *bson_iterator_regex( const bson_iterator *i ) { return bson_iterator_value( i ); } -const char *bson_iterator_regex_opts( const bson_iterator *i ) { +MONGO_EXPORT const char *bson_iterator_regex_opts( const bson_iterator *i ) { const char *p = bson_iterator_value( i ); return p + strlen( p ) + 1; } -void bson_iterator_subobject( const bson_iterator *i, bson *sub ) { +MONGO_EXPORT void bson_iterator_subobject( const bson_iterator *i, bson *sub ) { bson_init_data( sub, ( char * )bson_iterator_value( i ) ); _bson_reset( sub ); sub->finished = 1; } -void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ) { +MONGO_EXPORT void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ) { bson_iterator_from_buffer( sub, bson_iterator_value( i ) ); } @@ -578,7 +623,7 @@ static void _bson_init_size( bson *b, int size ) { _bson_reset( b ); } -void bson_init( bson *b ) { +MONGO_EXPORT void bson_init( bson *b ) { _bson_init_size( b, initialBufferSize ); } @@ -635,7 +680,7 @@ int bson_ensure_space( bson *b, const int bytesNeeded ) { return BSON_OK; } -int bson_finish( bson *b ) { +MONGO_EXPORT int bson_finish( bson *b ) { int i; if( b->err & BSON_NOT_UTF8 ) @@ -652,12 +697,14 @@ int bson_finish( bson *b ) { return BSON_OK; } -void bson_destroy( bson *b ) { - bson_free( b->data ); - b->err = 0; - b->data = 0; - b->cur = 0; - b->finished = 1; +MONGO_EXPORT void bson_destroy( bson *b ) { + if (b) { + bson_free( b->data ); + b->err = 0; + b->data = 0; + b->cur = 0; + b->finished = 1; + } } static int bson_append_estart( bson *b, int type, const char *name, const int dataSize ) { @@ -686,41 +733,41 @@ static int bson_append_estart( bson *b, int type, const char *name, const int da BUILDING TYPES ------------------------------ */ -int bson_append_int( bson *b, const char *name, const int i ) { +MONGO_EXPORT int bson_append_int( bson *b, const char *name, const int i ) { if ( bson_append_estart( b, BSON_INT, name, 4 ) == BSON_ERROR ) return BSON_ERROR; bson_append32( b , &i ); return BSON_OK; } -int bson_append_long( bson *b, const char *name, const int64_t i ) { +MONGO_EXPORT int bson_append_long( bson *b, const char *name, const int64_t i ) { if ( bson_append_estart( b , BSON_LONG, name, 8 ) == BSON_ERROR ) return BSON_ERROR; bson_append64( b , &i ); return BSON_OK; } -int bson_append_double( bson *b, const char *name, const double d ) { +MONGO_EXPORT int bson_append_double( bson *b, const char *name, const double d ) { if ( bson_append_estart( b, BSON_DOUBLE, name, 8 ) == BSON_ERROR ) return BSON_ERROR; bson_append64( b , &d ); return BSON_OK; } -int bson_append_bool( bson *b, const char *name, const bson_bool_t i ) { +MONGO_EXPORT int bson_append_bool( bson *b, const char *name, const bson_bool_t i ) { if ( bson_append_estart( b, BSON_BOOL, name, 1 ) == BSON_ERROR ) return BSON_ERROR; bson_append_byte( b , i != 0 ); return BSON_OK; } -int bson_append_null( bson *b, const char *name ) { +MONGO_EXPORT int bson_append_null( bson *b, const char *name ) { if ( bson_append_estart( b , BSON_NULL, name, 0 ) == BSON_ERROR ) return BSON_ERROR; return BSON_OK; } -int bson_append_undefined( bson *b, const char *name ) { +MONGO_EXPORT int bson_append_undefined( bson *b, const char *name ) { if ( bson_append_estart( b, BSON_UNDEFINED, name, 0 ) == BSON_ERROR ) return BSON_ERROR; return BSON_OK; @@ -741,31 +788,31 @@ int bson_append_string_base( bson *b, const char *name, return BSON_OK; } -int bson_append_string( bson *b, const char *name, const char *value ) { +MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *value ) { return bson_append_string_base( b, name, value, strlen ( value ), BSON_STRING ); } -int bson_append_symbol( bson *b, const char *name, const char *value ) { +MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *value ) { return bson_append_string_base( b, name, value, strlen ( value ), BSON_SYMBOL ); } -int bson_append_code( bson *b, const char *name, const char *value ) { +MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *value ) { return bson_append_string_base( b, name, value, strlen ( value ), BSON_CODE ); } -int bson_append_string_n( bson *b, const char *name, const char *value, int len ) { +MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *value, int len ) { return bson_append_string_base( b, name, value, len, BSON_STRING ); } -int bson_append_symbol_n( bson *b, const char *name, const char *value, int len ) { +MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *value, int len ) { return bson_append_string_base( b, name, value, len, BSON_SYMBOL ); } -int bson_append_code_n( bson *b, const char *name, const char *value, int len ) { +MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *value, int len ) { return bson_append_string_base( b, name, value, len, BSON_CODE ); } -int bson_append_code_w_scope_n( bson *b, const char *name, +MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int len, const bson *scope ) { int sl = len + 1; @@ -779,11 +826,11 @@ int bson_append_code_w_scope_n( bson *b, const char *name, return BSON_OK; } -int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ) { +MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ) { return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope ); } -int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ) { +MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ) { if ( type == BSON_BIN_BINARY_OLD ) { int subtwolen = len + 4; if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+4+len ) == BSON_ERROR ) @@ -802,20 +849,20 @@ int bson_append_binary( bson *b, const char *name, char type, const char *str, i return BSON_OK; } -int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ) { +MONGO_EXPORT int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ) { if ( bson_append_estart( b, BSON_OID, name, 12 ) == BSON_ERROR ) return BSON_ERROR; bson_append( b , oid , 12 ); return BSON_OK; } -int bson_append_new_oid( bson *b, const char *name ) { +MONGO_EXPORT int bson_append_new_oid( bson *b, const char *name ) { bson_oid_t oid; bson_oid_gen( &oid ); return bson_append_oid( b, name, &oid ); } -int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ) { +MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ) { const int plen = strlen( pattern )+1; const int olen = strlen( opts )+1; if ( bson_append_estart( b, BSON_REGEX, name, plen + olen ) == BSON_ERROR ) @@ -827,14 +874,14 @@ int bson_append_regex( bson *b, const char *name, const char *pattern, const cha return BSON_OK; } -int bson_append_bson( bson *b, const char *name, const bson *bson ) { +MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson ) { if ( bson_append_estart( b, BSON_OBJECT, name, bson_size( bson ) ) == BSON_ERROR ) return BSON_ERROR; bson_append( b , bson->data , bson_size( bson ) ); return BSON_OK; } -int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) { +MONGO_EXPORT int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) { bson_iterator next = *elem; int size; @@ -854,7 +901,7 @@ int bson_append_element( bson *b, const char *name_or_null, const bson_iterator return BSON_OK; } -int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) { +MONGO_EXPORT int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) { if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR; bson_append32( b , &( ts->i ) ); @@ -863,31 +910,39 @@ int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) { return BSON_OK; } -int bson_append_date( bson *b, const char *name, bson_date_t millis ) { +MONGO_EXPORT int bson_append_timestamp2( bson *b, const char *name, int time, int increment ) { + if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR; + + bson_append32( b , &increment ); + bson_append32( b , &time ); + return BSON_OK; +} + +MONGO_EXPORT int bson_append_date( bson *b, const char *name, bson_date_t millis ) { if ( bson_append_estart( b, BSON_DATE, name, 8 ) == BSON_ERROR ) return BSON_ERROR; bson_append64( b , &millis ); return BSON_OK; } -int bson_append_time_t( bson *b, const char *name, time_t secs ) { +MONGO_EXPORT int bson_append_time_t( bson *b, const char *name, time_t secs ) { return bson_append_date( b, name, ( bson_date_t )secs * 1000 ); } -int bson_append_start_object( bson *b, const char *name ) { +MONGO_EXPORT int bson_append_start_object( bson *b, const char *name ) { if ( bson_append_estart( b, BSON_OBJECT, name, 5 ) == BSON_ERROR ) return BSON_ERROR; b->stack[ b->stackPos++ ] = b->cur - b->data; bson_append32( b , &zero ); return BSON_OK; } -int bson_append_start_array( bson *b, const char *name ) { +MONGO_EXPORT int bson_append_start_array( bson *b, const char *name ) { if ( bson_append_estart( b, BSON_ARRAY, name, 5 ) == BSON_ERROR ) return BSON_ERROR; b->stack[ b->stackPos++ ] = b->cur - b->data; bson_append32( b , &zero ); return BSON_OK; } -int bson_append_finish_object( bson *b ) { +MONGO_EXPORT int bson_append_finish_object( bson *b ) { char *start; int i; if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR; @@ -900,22 +955,25 @@ int bson_append_finish_object( bson *b ) { return BSON_OK; } -int bson_append_finish_array( bson *b ) { - return bson_append_finish_object( b ); +MONGO_EXPORT double bson_int64_to_double( int64_t i64 ) { + return (double)i64; } +MONGO_EXPORT int bson_append_finish_array( bson *b ) { + return bson_append_finish_object( b ); +} /* Error handling and allocators. */ static bson_err_handler err_handler = NULL; -bson_err_handler set_bson_err_handler( bson_err_handler func ) { +MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func ) { bson_err_handler old = err_handler; err_handler = func; return old; } -void *bson_malloc( int size ) { +MONGO_EXPORT void *bson_malloc( int size ) { void *p; p = bson_malloc_func( size ); bson_fatal_msg( !!p, "malloc() failed" ); @@ -933,7 +991,9 @@ int _bson_errprintf( const char *format, ... ) { va_list ap; int ret; va_start( ap, format ); +#ifndef R_SAFETY_NET ret = vfprintf( stderr, format, ap ); +#endif va_end( ap ); return ret; @@ -961,9 +1021,10 @@ void bson_fatal_msg( int ok , const char *msg ) { if ( err_handler ) { err_handler( msg ); } - +#ifndef R_SAFETY_NET bson_errprintf( "error: %s\n" , msg ); exit( -5 ); +#endif } @@ -976,3 +1037,28 @@ void bson_numstr( char *str, int i ) { else bson_sprintf( str,"%d", i ); } + +MONGO_EXPORT void bson_swap_endian64( void *outp, const void *inp ) { + const char *in = ( const char * )inp; + char *out = ( char * )outp; + + out[0] = in[7]; + out[1] = in[6]; + out[2] = in[5]; + out[3] = in[4]; + out[4] = in[3]; + out[5] = in[2]; + out[6] = in[1]; + out[7] = in[0]; + +} + +MONGO_EXPORT void bson_swap_endian32( void *outp, const void *inp ) { + const char *in = ( const char * )inp; + char *out = ( char * )outp; + + out[0] = in[3]; + out[1] = in[2]; + out[2] = in[1]; + out[3] = in[0]; +} diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.h index 2e385b9160..b83d1ca9c9 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.h +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.h @@ -3,7 +3,7 @@ * @brief BSON Declarations */ -/* Copyright 2009-2011 10gen Inc. +/* Copyright 2009-2012 10gen Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,16 +18,63 @@ * limitations under the License. */ -#ifndef _BSON_H_ -#define _BSON_H_ +#ifndef BSON_H_ +#define BSON_H_ -#include "platform.h" #include <time.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> +#ifdef __GNUC__ + #define MONGO_INLINE static __inline__ + #define MONGO_EXPORT +#else + #define MONGO_INLINE static + #ifdef MONGO_STATIC_BUILD + #define MONGO_EXPORT + #elif defined(MONGO_DLL_BUILD) + #define MONGO_EXPORT __declspec(dllexport) + #else + #define MONGO_EXPORT __declspec(dllimport) + #endif +#endif + +#ifdef __cplusplus +#define MONGO_EXTERN_C_START extern "C" { +#define MONGO_EXTERN_C_END } +#else +#define MONGO_EXTERN_C_START +#define MONGO_EXTERN_C_END +#endif + +#if defined(MONGO_HAVE_STDINT) || __STDC_VERSION__ >= 199901L +#include <stdint.h> +#elif defined(MONGO_HAVE_UNISTD) +#include <unistd.h> +#elif defined(MONGO_USE__INT64) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#elif defined(MONGO_USE_LONG_LONG_INT) +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#else +#error Must compile with c99 or define MONGO_HAVE_STDINT, MONGO_HAVE_UNISTD, MONGO_USE__INT64, or MONGO_USE_LONG_INT. +#endif + +#ifdef MONGO_BIG_ENDIAN +#define bson_little_endian64(out, in) ( bson_swap_endian64(out, in) ) +#define bson_little_endian32(out, in) ( bson_swap_endian32(out, in) ) +#define bson_big_endian64(out, in) ( memcpy(out, in, 8) ) +#define bson_big_endian32(out, in) ( memcpy(out, in, 4) ) +#else +#define bson_little_endian64(out, in) ( memcpy(out, in, 8) ) +#define bson_little_endian32(out, in) ( memcpy(out, in, 4) ) +#define bson_big_endian64(out, in) ( bson_swap_endian64(out, in) ) +#define bson_big_endian32(out, in) ( bson_swap_endian32(out, in) ) +#endif + MONGO_EXTERN_C_START #define BSON_OK 0 @@ -84,12 +131,12 @@ typedef struct { } bson_iterator; typedef struct { - char *data; - char *cur; - int dataSize; - bson_bool_t finished; - int stack[32]; - int stackPos; + char *data; /**< Pointer to a block of data in this BSON object. */ + char *cur; /**< Pointer to the current position. */ + int dataSize; /**< The number of bytes allocated to char *data. */ + bson_bool_t finished; /**< When finished, the BSON object can no longer be modified. */ + int stack[32]; /**< A stack used to keep track of nested BSON elements. */ + int stackPos; /**< Index of current stack position. */ int err; /**< Bitfield representing errors or warnings on this buffer */ char *errstr; /**< A string representation of the most recent error or warning. */ } bson; @@ -112,6 +159,9 @@ typedef struct { READING ------------------------------ */ +MONGO_EXPORT bson* bson_create(); +MONGO_EXPORT void bson_dispose(bson* b); + /** * Size of a BSON object. * @@ -119,21 +169,22 @@ typedef struct { * * @return the size. */ -int bson_size( const bson *b ); +MONGO_EXPORT int bson_size( const bson *b ); +MONGO_EXPORT int bson_buffer_size( const bson *b ); /** * Print a string representation of a BSON object. * * @param b the BSON object to print. */ -void bson_print( bson *b ); +MONGO_EXPORT void bson_print( const bson *b ); /** * Return a pointer to the raw buffer stored by this bson object. * * @param b a BSON object */ -const char *bson_data( bson *b ); +MONGO_EXPORT const char *bson_data( const bson *b ); /** * Print a string representation of a BSON object. @@ -141,7 +192,7 @@ const char *bson_data( bson *b ); * @param bson the raw data to print. * @param depth the depth to recurse the object.x */ -void bson_print_raw( const char *bson , int depth ); +MONGO_EXPORT void bson_print_raw( const char *bson , int depth ); /** * Advance a bson_iterator to the named field. @@ -152,15 +203,18 @@ void bson_print_raw( const char *bson , int depth ); * * @return the type of the found object or BSON_EOO if it is not found. */ -bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ); +MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ); + +MONGO_EXPORT bson_iterator* bson_iterator_create(); +MONGO_EXPORT void bson_iterator_dispose(bson_iterator*); /** * Initialize a bson_iterator. * * @param i the bson_iterator to initialize. * @param bson the BSON object to associate with the iterator. */ -void bson_iterator_init( bson_iterator *i , const bson *b ); +MONGO_EXPORT void bson_iterator_init( bson_iterator *i , const bson *b ); /** * Initialize a bson iterator from a const char* buffer. Note @@ -169,7 +223,7 @@ void bson_iterator_init( bson_iterator *i , const bson *b ); * @param i the bson_iterator to initialize. * @param buffer the buffer to point to. */ -void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ); +MONGO_EXPORT void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ); /* more returns true for eoo. best to loop with bson_iterator_next(&it) */ /** @@ -179,7 +233,7 @@ void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ); * * @return returns true if there is more data. */ -bson_bool_t bson_iterator_more( const bson_iterator *i ); +MONGO_EXPORT bson_bool_t bson_iterator_more( const bson_iterator *i ); /** * Point the iterator at the next BSON object. @@ -188,7 +242,7 @@ bson_bool_t bson_iterator_more( const bson_iterator *i ); * * @return the type of the next BSON object. */ -bson_type bson_iterator_next( bson_iterator *i ); +MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i ); /** * Get the type of the BSON object currently pointed to by the iterator. @@ -197,7 +251,7 @@ bson_type bson_iterator_next( bson_iterator *i ); * * @return the type of the current BSON object. */ -bson_type bson_iterator_type( const bson_iterator *i ); +MONGO_EXPORT bson_type bson_iterator_type( const bson_iterator *i ); /** * Get the key of the BSON object currently pointed to by the iterator. @@ -206,7 +260,7 @@ bson_type bson_iterator_type( const bson_iterator *i ); * * @return the key of the current BSON object. */ -const char *bson_iterator_key( const bson_iterator *i ); +MONGO_EXPORT const char *bson_iterator_key( const bson_iterator *i ); /** * Get the value of the BSON object currently pointed to by the iterator. @@ -215,7 +269,7 @@ const char *bson_iterator_key( const bson_iterator *i ); * * @return the value of the current BSON object. */ -const char *bson_iterator_value( const bson_iterator *i ); +MONGO_EXPORT const char *bson_iterator_value( const bson_iterator *i ); /* these convert to the right type (return 0 if non-numeric) */ /** @@ -226,7 +280,7 @@ const char *bson_iterator_value( const bson_iterator *i ); * * @return the value of the current BSON object. */ -double bson_iterator_double( const bson_iterator *i ); +MONGO_EXPORT double bson_iterator_double( const bson_iterator *i ); /** * Get the int value of the BSON object currently pointed to by the iterator. @@ -235,7 +289,7 @@ double bson_iterator_double( const bson_iterator *i ); * * @return the value of the current BSON object. */ -int bson_iterator_int( const bson_iterator *i ); +MONGO_EXPORT int bson_iterator_int( const bson_iterator *i ); /** * Get the long value of the BSON object currently pointed to by the iterator. @@ -244,7 +298,7 @@ int bson_iterator_int( const bson_iterator *i ); * * @return the value of the current BSON object. */ -int64_t bson_iterator_long( const bson_iterator *i ); +MONGO_EXPORT int64_t bson_iterator_long( const bson_iterator *i ); /* return the bson timestamp as a whole or in parts */ /** @@ -255,7 +309,9 @@ int64_t bson_iterator_long( const bson_iterator *i ); * * @return the value of the current BSON object. */ -bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ); +MONGO_EXPORT bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ); +MONGO_EXPORT int bson_iterator_timestamp_time( const bson_iterator *i ); +MONGO_EXPORT int bson_iterator_timestamp_increment( const bson_iterator *i ); /** * Get the boolean value of the BSON object currently pointed to by @@ -267,7 +323,7 @@ bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ); */ /* false: boolean false, 0 in any type, or null */ /* true: anything else (even empty strings and objects) */ -bson_bool_t bson_iterator_bool( const bson_iterator *i ); +MONGO_EXPORT bson_bool_t bson_iterator_bool( const bson_iterator *i ); /** * Get the double value of the BSON object currently pointed to by the @@ -318,7 +374,7 @@ bson_bool_t bson_iterator_bool_raw( const bson_iterator *i ); * * @return the value of the current BSON object. */ -bson_oid_t *bson_iterator_oid( const bson_iterator *i ); +MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i ); /** * Get the string value of the BSON object currently pointed to by the @@ -329,7 +385,7 @@ bson_oid_t *bson_iterator_oid( const bson_iterator *i ); * @return the value of the current BSON object. */ /* these can also be used with bson_code and bson_symbol*/ -const char *bson_iterator_string( const bson_iterator *i ); +MONGO_EXPORT const char *bson_iterator_string( const bson_iterator *i ); /** * Get the string length of the BSON object currently pointed to by the @@ -352,7 +408,7 @@ int bson_iterator_string_len( const bson_iterator *i ); */ /* works with bson_code, bson_codewscope, and BSON_STRING */ /* returns NULL for everything else */ -const char *bson_iterator_code( const bson_iterator *i ); +MONGO_EXPORT const char *bson_iterator_code( const bson_iterator *i ); /** * Calls bson_empty on scope if not a bson_codewscope @@ -361,7 +417,7 @@ const char *bson_iterator_code( const bson_iterator *i ); * @param scope the bson scope. */ /* calls bson_empty on scope if not a bson_codewscope */ -void bson_iterator_code_scope( const bson_iterator *i, bson *scope ); +MONGO_EXPORT void bson_iterator_code_scope( const bson_iterator *i, bson *scope ); /** * Get the date value of the BSON object currently pointed to by the @@ -372,7 +428,7 @@ void bson_iterator_code_scope( const bson_iterator *i, bson *scope ); * @return the date value of the current BSON object. */ /* both of these only work with bson_date */ -bson_date_t bson_iterator_date( const bson_iterator *i ); +MONGO_EXPORT bson_date_t bson_iterator_date( const bson_iterator *i ); /** * Get the time value of the BSON object currently pointed to by the @@ -382,7 +438,7 @@ bson_date_t bson_iterator_date( const bson_iterator *i ); * * @return the time value of the current BSON object. */ -time_t bson_iterator_time_t( const bson_iterator *i ); +MONGO_EXPORT time_t bson_iterator_time_t( const bson_iterator *i ); /** * Get the length of the BSON binary object currently pointed to by the @@ -392,7 +448,7 @@ time_t bson_iterator_time_t( const bson_iterator *i ); * * @return the length of the current BSON binary object. */ -int bson_iterator_bin_len( const bson_iterator *i ); +MONGO_EXPORT int bson_iterator_bin_len( const bson_iterator *i ); /** * Get the type of the BSON binary object currently pointed to by the @@ -402,7 +458,7 @@ int bson_iterator_bin_len( const bson_iterator *i ); * * @return the type of the current BSON binary object. */ -char bson_iterator_bin_type( const bson_iterator *i ); +MONGO_EXPORT char bson_iterator_bin_type( const bson_iterator *i ); /** * Get the value of the BSON binary object currently pointed to by the @@ -412,7 +468,7 @@ char bson_iterator_bin_type( const bson_iterator *i ); * * @return the value of the current BSON binary object. */ -const char *bson_iterator_bin_data( const bson_iterator *i ); +MONGO_EXPORT const char *bson_iterator_bin_data( const bson_iterator *i ); /** * Get the value of the BSON regex object currently pointed to by the @@ -422,7 +478,7 @@ const char *bson_iterator_bin_data( const bson_iterator *i ); * * @return the value of the current BSON regex object. */ -const char *bson_iterator_regex( const bson_iterator *i ); +MONGO_EXPORT const char *bson_iterator_regex( const bson_iterator *i ); /** * Get the options of the BSON regex object currently pointed to by the @@ -432,7 +488,7 @@ const char *bson_iterator_regex( const bson_iterator *i ); * * @return the options of the current BSON regex object. */ -const char *bson_iterator_regex_opts( const bson_iterator *i ); +MONGO_EXPORT const char *bson_iterator_regex_opts( const bson_iterator *i ); /* these work with BSON_OBJECT and BSON_ARRAY */ /** @@ -442,7 +498,7 @@ const char *bson_iterator_regex_opts( const bson_iterator *i ); * @param i the bson_iterator. * @param sub the BSON subobject destination. */ -void bson_iterator_subobject( const bson_iterator *i, bson *sub ); +MONGO_EXPORT void bson_iterator_subobject( const bson_iterator *i, bson *sub ); /** * Get a bson_iterator that on the BSON subobject. @@ -450,7 +506,7 @@ void bson_iterator_subobject( const bson_iterator *i, bson *sub ); * @param i the bson_iterator. * @param sub the iterator to point at the BSON subobject. */ -void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ); +MONGO_EXPORT void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ); /* str must be at least 24 hex chars + null byte */ /** @@ -459,7 +515,7 @@ void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ); * @param oid the bson_oid_t destination. * @param str a null terminated string comprised of at least 24 hex chars. */ -void bson_oid_from_string( bson_oid_t *oid, const char *str ); +MONGO_EXPORT void bson_oid_from_string( bson_oid_t *oid, const char *str ); /** * Create a string representation of the bson_oid_t. @@ -467,14 +523,14 @@ void bson_oid_from_string( bson_oid_t *oid, const char *str ); * @param oid the bson_oid_t source. * @param str the string representation destination. */ -void bson_oid_to_string( const bson_oid_t *oid, char *str ); +MONGO_EXPORT void bson_oid_to_string( const bson_oid_t *oid, char *str ); /** * Create a bson_oid object. * * @param oid the destination for the newly created bson_oid_t. */ -void bson_oid_gen( bson_oid_t *oid ); +MONGO_EXPORT void bson_oid_gen( bson_oid_t *oid ); /** * Set a function to be used to generate the second four bytes @@ -482,7 +538,7 @@ void bson_oid_gen( bson_oid_t *oid ); * * @param func a pointer to a function that returns an int. */ -void bson_set_oid_fuzz( int ( *func )( void ) ); +MONGO_EXPORT void bson_set_oid_fuzz( int ( *func )( void ) ); /** * Set a function to be used to generate the incrementing part @@ -491,14 +547,14 @@ void bson_set_oid_fuzz( int ( *func )( void ) ); * * @param func a pointer to a function that returns an int. */ -void bson_set_oid_inc( int ( *func )( void ) ); +MONGO_EXPORT void bson_set_oid_inc( int ( *func )( void ) ); /** * Get the time a bson_oid_t was created. * * @param oid the bson_oid_t. */ -time_t bson_oid_generated_time( bson_oid_t *oid ); /* Gives the time the OID was created */ +MONGO_EXPORT time_t bson_oid_generated_time( bson_oid_t *oid ); /* Gives the time the OID was created */ /* ---------------------------- BUILDING @@ -512,7 +568,7 @@ time_t bson_oid_generated_time( bson_oid_t *oid ); /* Gives the time the OID was * @note When finished, you must pass the bson object to * bson_destroy( ). */ -void bson_init( bson *b ); +MONGO_EXPORT void bson_init( bson *b ); /** * Initialize a BSON object, and point its data @@ -524,6 +580,7 @@ void bson_init( bson *b ); * @return BSON_OK or BSON_ERROR. */ int bson_init_data( bson *b , char *data ); +int bson_init_finished_data( bson *b, char *data ) ; /** * Initialize a BSON object, and set its @@ -555,7 +612,7 @@ int bson_ensure_space( bson *b, const int bytesNeeded ); * @return the standard error code. To deallocate memory, * call bson_destroy on the bson object. */ -int bson_finish( bson *b ); +MONGO_EXPORT int bson_finish( bson *b ); /** * Destroy a bson object. @@ -563,7 +620,7 @@ int bson_finish( bson *b ); * @param b the bson object to destroy. * */ -void bson_destroy( bson *b ); +MONGO_EXPORT void bson_destroy( bson *b ); /** * Returns a pointer to a static empty BSON object. @@ -573,23 +630,17 @@ void bson_destroy( bson *b ); * @return the empty initialized BSON object. */ /* returns pointer to static empty bson object */ -bson *bson_empty( bson *obj ); - -/** - * Copy BSON data only from one object to another. - * - * @param out the copy destination BSON object. - * @param in the copy source BSON object. - */ -void bson_copy_basic( bson *out, const bson *in ); +MONGO_EXPORT bson *bson_empty( bson *obj ); /** * Make a complete copy of the a BSON object. + * The source bson object must be in a finished + * state; otherwise, the copy will fail. * * @param out the copy destination BSON object. * @param in the copy source BSON object. */ -void bson_copy( bson *out, const bson *in ); /* puts data in new buffer. NOOP if out==NULL */ +MONGO_EXPORT int bson_copy( bson *out, const bson *in ); /* puts data in new buffer. NOOP if out==NULL */ /** * Append a previously created bson_oid_t to a bson object. @@ -600,7 +651,7 @@ void bson_copy( bson *out, const bson *in ); /* puts data in new buffer. NOOP if * * @return BSON_OK or BSON_ERROR. */ -int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ); +MONGO_EXPORT int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ); /** * Append a bson_oid_t to a bson. @@ -610,7 +661,7 @@ int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_new_oid( bson *b, const char *name ); +MONGO_EXPORT int bson_append_new_oid( bson *b, const char *name ); /** * Append an int to a bson. @@ -621,7 +672,7 @@ int bson_append_new_oid( bson *b, const char *name ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_int( bson *b, const char *name, const int i ); +MONGO_EXPORT int bson_append_int( bson *b, const char *name, const int i ); /** * Append an long to a bson. @@ -632,7 +683,7 @@ int bson_append_int( bson *b, const char *name, const int i ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_long( bson *b, const char *name, const int64_t i ); +MONGO_EXPORT int bson_append_long( bson *b, const char *name, const int64_t i ); /** * Append an double to a bson. @@ -643,7 +694,7 @@ int bson_append_long( bson *b, const char *name, const int64_t i ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_double( bson *b, const char *name, const double d ); +MONGO_EXPORT int bson_append_double( bson *b, const char *name, const double d ); /** * Append a string to a bson. @@ -654,7 +705,7 @@ int bson_append_double( bson *b, const char *name, const double d ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_string( bson *b, const char *name, const char *str ); +MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *str ); /** * Append len bytes of a string to a bson. @@ -666,7 +717,7 @@ int bson_append_string( bson *b, const char *name, const char *str ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_string_n( bson *b, const char *name, const char *str, int len ); +MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *str, int len ); /** * Append a symbol to a bson. @@ -677,7 +728,7 @@ int bson_append_string_n( bson *b, const char *name, const char *str, int len ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_symbol( bson *b, const char *name, const char *str ); +MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *str ); /** * Append len bytes of a symbol to a bson. @@ -689,7 +740,7 @@ int bson_append_symbol( bson *b, const char *name, const char *str ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_symbol_n( bson *b, const char *name, const char *str, int len ); +MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *str, int len ); /** * Append code to a bson. @@ -701,7 +752,7 @@ int bson_append_symbol_n( bson *b, const char *name, const char *str, int len ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_code( bson *b, const char *name, const char *str ); +MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *str ); /** * Append len bytes of code to a bson. @@ -713,7 +764,7 @@ int bson_append_code( bson *b, const char *name, const char *str ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_code_n( bson *b, const char *name, const char *str, int len ); +MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *str, int len ); /** * Append code to a bson with scope. @@ -725,7 +776,7 @@ int bson_append_code_n( bson *b, const char *name, const char *str, int len ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ); +MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ); /** * Append len bytes of code to a bson with scope. @@ -738,7 +789,7 @@ int bson_append_code_w_scope( bson *b, const char *name, const char *code, const * * @return BSON_OK or BSON_ERROR. */ -int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int size, const bson *scope ); +MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int size, const bson *scope ); /** * Append binary data to a bson. @@ -751,7 +802,7 @@ int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int * * @return BSON_OK or BSON_ERROR. */ -int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ); +MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ); /** * Append a bson_bool_t to a bson. @@ -762,7 +813,7 @@ int bson_append_binary( bson *b, const char *name, char type, const char *str, i * * @return BSON_OK or BSON_ERROR. */ -int bson_append_bool( bson *b, const char *name, const bson_bool_t v ); +MONGO_EXPORT int bson_append_bool( bson *b, const char *name, const bson_bool_t v ); /** * Append a null value to a bson. @@ -772,7 +823,7 @@ int bson_append_bool( bson *b, const char *name, const bson_bool_t v ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_null( bson *b, const char *name ); +MONGO_EXPORT int bson_append_null( bson *b, const char *name ); /** * Append an undefined value to a bson. @@ -782,7 +833,7 @@ int bson_append_null( bson *b, const char *name ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_undefined( bson *b, const char *name ); +MONGO_EXPORT int bson_append_undefined( bson *b, const char *name ); /** * Append a regex value to a bson. @@ -794,7 +845,7 @@ int bson_append_undefined( bson *b, const char *name ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ); +MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ); /** * Append bson data to a bson. @@ -805,7 +856,7 @@ int bson_append_regex( bson *b, const char *name, const char *pattern, const cha * * @return BSON_OK or BSON_ERROR. */ -int bson_append_bson( bson *b, const char *name, const bson *bson ); +MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson ); /** * Append a BSON element to a bson from the current point of an iterator. @@ -816,7 +867,7 @@ int bson_append_bson( bson *b, const char *name, const bson *bson ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ); +MONGO_EXPORT int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ); /** * Append a bson_timestamp_t value to a bson. @@ -827,7 +878,8 @@ int bson_append_element( bson *b, const char *name_or_null, const bson_iterator * * @return BSON_OK or BSON_ERROR. */ -int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ); +MONGO_EXPORT int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ); +MONGO_EXPORT int bson_append_timestamp2( bson *b, const char *name, int time, int increment ); /* these both append a bson_date */ /** @@ -839,7 +891,7 @@ int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_date( bson *b, const char *name, bson_date_t millis ); +MONGO_EXPORT int bson_append_date( bson *b, const char *name, bson_date_t millis ); /** * Append a time_t value to a bson. @@ -850,7 +902,7 @@ int bson_append_date( bson *b, const char *name, bson_date_t millis ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_time_t( bson *b, const char *name, time_t secs ); +MONGO_EXPORT int bson_append_time_t( bson *b, const char *name, time_t secs ); /** * Start appending a new object to a bson. @@ -860,7 +912,7 @@ int bson_append_time_t( bson *b, const char *name, time_t secs ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_start_object( bson *b, const char *name ); +MONGO_EXPORT int bson_append_start_object( bson *b, const char *name ); /** * Start appending a new array to a bson. @@ -870,7 +922,7 @@ int bson_append_start_object( bson *b, const char *name ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_start_array( bson *b, const char *name ); +MONGO_EXPORT int bson_append_start_array( bson *b, const char *name ); /** * Finish appending a new object or array to a bson. @@ -879,7 +931,7 @@ int bson_append_start_array( bson *b, const char *name ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_finish_object( bson *b ); +MONGO_EXPORT int bson_append_finish_object( bson *b ); /** * Finish appending a new object or array to a bson. This @@ -889,13 +941,13 @@ int bson_append_finish_object( bson *b ); * * @return BSON_OK or BSON_ERROR. */ -int bson_append_finish_array( bson *b ); +MONGO_EXPORT int bson_append_finish_array( bson *b ); void bson_numstr( char *str, int i ); void bson_incnumstr( char *str ); -/* Error handling and stadard library function over-riding. */ +/* Error handling and standard library function over-riding. */ /* -------------------------------------------------------- */ /* bson_err_handlers shouldn't return!!! */ @@ -912,7 +964,6 @@ extern void ( *bson_free )( void * ); extern bson_printf_func bson_printf; extern bson_fprintf_func bson_fprintf; extern bson_sprintf_func bson_sprintf; - extern bson_printf_func bson_errprintf; /** @@ -924,7 +975,7 @@ extern bson_printf_func bson_errprintf; * * @sa malloc(3) */ -void *bson_malloc( int size ); +MONGO_EXPORT void *bson_malloc( int size ); /** * Changes the size of allocated memory and checks return value, @@ -946,7 +997,7 @@ void *bson_realloc( void *ptr, int size ); * * @return the old error handling function, or NULL. */ -bson_err_handler set_bson_err_handler( bson_err_handler func ); +MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func ); /* does nothing if ok != 0 */ /** @@ -971,5 +1022,15 @@ void bson_fatal_msg( int ok, const char *msg ); */ void bson_builder_error( bson *b ); +/** + * Cast an int64_t to double. This is necessary for embedding in + * certain environments. + * + */ +MONGO_EXPORT double bson_int64_to_double( int64_t i64 ); + +MONGO_EXPORT void bson_swap_endian32( void *outp, const void *inp ); +MONGO_EXPORT void bson_swap_endian64( void *outp, const void *inp ); + MONGO_EXTERN_C_END #endif diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.c index 8d2da1502f..00ecf18c92 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2011 10gen, Inc. + * Copyright 2009-2012 10gen, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.h index a2a07c6d5d..f13c31ee89 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.h +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2011 10gen, Inc. + * Copyright 2009-2012 10gen, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef _BSON_ENCODING_H_ -#define _BSON_ENCODING_H_ +#ifndef BSON_ENCODING_H_ +#define BSON_ENCODING_H_ MONGO_EXTERN_C_START diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env.h new file mode 100644 index 0000000000..463ee32f79 --- /dev/null +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env.h @@ -0,0 +1,39 @@ +/** @file env.h */ + +/* Copyright 2009-2012 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Header for generic net.h */ +#ifndef MONGO_ENV_H_ +#define MONGO_ENV_H_ + +#include "mongo.h" + +MONGO_EXTERN_C_START + +/* This is a no-op in the generic implementation. */ +int mongo_env_set_socket_op_timeout( mongo *conn, int millis ); +int mongo_env_read_socket( mongo *conn, void *buf, int len ); +int mongo_env_write_socket( mongo *conn, const void *buf, int len ); +int mongo_env_socket_connect( mongo *conn, const char *host, int port ); + +/* Initialize socket services */ +MONGO_EXPORT int mongo_env_sock_init( void ); + +/* Close a socket */ +MONGO_EXPORT int mongo_env_close_socket( int socket ); + +MONGO_EXTERN_C_END +#endif diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c new file mode 100644 index 0000000000..f1020ca80d --- /dev/null +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c @@ -0,0 +1,165 @@ +/* env_posix.c */ + +/* Copyright 2009-2012 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Networking and other niceties for POSIX systems. */ +#include "env.h" +#include "mongo.h" +#include <string.h> +#include <errno.h> +#include <sys/time.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <fcntl.h> +#include <unistd.h> + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif + +int mongo_env_close_socket( int socket ) { + return close( socket ); +} + +int mongo_env_sock_init( void ) { + return 0; +} + +int mongo_env_write_socket( mongo *conn, const void *buf, int len ) { + const char *cbuf = buf; +#ifdef __APPLE__ + int flags = 0; +#else + int flags = MSG_NOSIGNAL; +#endif + + while ( len ) { + int sent = send( conn->sock, cbuf, len, flags ); + if ( sent == -1 ) { + if (errno == EPIPE) + conn->connected = 0; + __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno ); + return MONGO_ERROR; + } + cbuf += sent; + len -= sent; + } + + return MONGO_OK; +} + +int mongo_env_read_socket( mongo *conn, void *buf, int len ) { + char *cbuf = buf; + while ( len ) { + int sent = recv( conn->sock, cbuf, len, 0 ); + if ( sent == 0 || sent == -1 ) { + __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno ); + return MONGO_ERROR; + } + cbuf += sent; + len -= sent; + } + + return MONGO_OK; +} + +int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) { + struct timeval tv; + tv.tv_sec = millis / 1000; + tv.tv_usec = ( millis % 1000 ) * 1000; + + if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) ) == -1 ) { + conn->err = MONGO_IO_ERROR; + __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.", errno ); + return MONGO_ERROR; + } + + if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof( tv ) ) == -1 ) { + __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.", errno ); + return MONGO_ERROR; + } + + return MONGO_OK; +} + +int mongo_env_socket_connect( mongo *conn, const char *host, int port ) { + char port_str[NI_MAXSERV]; + int status; + + struct addrinfo ai_hints; + struct addrinfo *ai_list = NULL; + struct addrinfo *ai_ptr = NULL; + + conn->sock = 0; + conn->connected = 0; + sprintf(port_str,"%d",port); + + bson_sprintf( port_str, "%d", port ); + + memset( &ai_hints, 0, sizeof( ai_hints ) ); +#ifdef AI_ADDRCONFIG + ai_hints.ai_flags = AI_ADDRCONFIG; +#endif + ai_hints.ai_family = AF_UNSPEC; + ai_hints.ai_socktype = SOCK_STREAM; + + status = getaddrinfo( host, port_str, &ai_hints, &ai_list ); + if ( status != 0 ) { + bson_errprintf( "getaddrinfo failed: %s", gai_strerror( status ) ); + conn->err = MONGO_CONN_ADDR_FAIL; + return MONGO_ERROR; + } + + for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) { + conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol ); + if ( conn->sock < 0 ) { + conn->sock = 0; + continue; + } + + status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen ); + if ( status != 0 ) { + mongo_env_close_socket( conn->sock ); + conn->sock = 0; + continue; + } + + if ( ai_ptr->ai_protocol == IPPROTO_TCP ) { + int flag = 1; + + setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, + ( void * ) &flag, sizeof( flag ) ); + if ( conn->op_timeout_ms > 0 ) + mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms ); + } + + conn->connected = 1; + break; + } + + freeaddrinfo( ai_list ); + + if ( ! conn->connected ) { + conn->err = MONGO_CONN_FAIL; + return MONGO_ERROR; + } + + return MONGO_OK; +} diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_standard.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_standard.c new file mode 100644 index 0000000000..36fa9f65c4 --- /dev/null +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_standard.c @@ -0,0 +1,168 @@ +/* env_standard.c */ + +/* Copyright 2009-2012 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Vanilla networking designed to work on all systems. */ +#include "env.h" +#include <errno.h> +#include <string.h> + +#ifdef _WIN32 + #ifdef _MSC_VER + #include <ws2tcpip.h> // send,recv,socklen_t etc + #include <wspiapi.h> // addrinfo + #else + #include <windows.h> + #include <winsock.h> + typedef int socklen_t; + #endif +#else +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <fcntl.h> +#include <unistd.h> +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif + +int mongo_env_close_socket( int socket ) { +#ifdef _WIN32 + return closesocket( socket ); +#else + return close( socket ); +#endif +} + +int mongo_env_write_socket( mongo *conn, const void *buf, int len ) { + const char *cbuf = buf; +#ifdef _WIN32 + int flags = 0; +#else +#ifdef __APPLE__ + int flags = 0; +#else + int flags = MSG_NOSIGNAL; +#endif +#endif + + while ( len ) { + int sent = send( conn->sock, cbuf, len, flags ); + if ( sent == -1 ) { + if (errno == EPIPE) + conn->connected = 0; + conn->err = MONGO_IO_ERROR; + return MONGO_ERROR; + } + cbuf += sent; + len -= sent; + } + + return MONGO_OK; +} + +int mongo_env_read_socket( mongo *conn, void *buf, int len ) { + char *cbuf = buf; + while ( len ) { + int sent = recv( conn->sock, cbuf, len, 0 ); + if ( sent == 0 || sent == -1 ) { + conn->err = MONGO_IO_ERROR; + return MONGO_ERROR; + } + cbuf += sent; + len -= sent; + } + + return MONGO_OK; +} + +/* This is a no-op in the generic implementation. */ +int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) { + return MONGO_OK; +} + +int mongo_env_socket_connect( mongo *conn, const char *host, int port ) { + struct sockaddr_in sa; + socklen_t addressSize; + int flag = 1; + + if ( ( conn->sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { + conn->sock = 0; + conn->err = MONGO_CONN_NO_SOCKET; + return MONGO_ERROR; + } + + memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) ); + sa.sin_family = AF_INET; + sa.sin_port = htons( port ); + sa.sin_addr.s_addr = inet_addr( host ); + addressSize = sizeof( sa ); + + if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) { + mongo_env_close_socket( conn->sock ); + conn->connected = 0; + conn->sock = 0; + conn->err = MONGO_CONN_FAIL; + return MONGO_ERROR; + } + + setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) ); + + if( conn->op_timeout_ms > 0 ) + mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms ); + + conn->connected = 1; + + return MONGO_OK; +} + +MONGO_EXPORT int mongo_env_sock_init( void ) { + +#if defined(_WIN32) + WSADATA wsaData; + WORD wVers; +#elif defined(SIGPIPE) + struct sigaction act; +#endif + + static int called_once; + static int retval; + if (called_once) return retval; + called_once = 1; + +#if defined(_WIN32) + wVers = MAKEWORD(1, 1); + retval = (WSAStartup(wVers, &wsaData) == 0); +#elif defined(MACINTOSH) + GUSISetup(GUSIwithInternetSockets); + retval = 1; +#elif defined(SIGPIPE) + retval = 1; + if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) < 0) + retval = 0; + else if (act.sa_handler == SIG_DFL) { + act.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) < 0) + retval = 0; + } +#endif + return retval; +} diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_win32.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_win32.c new file mode 100644 index 0000000000..0b301cea61 --- /dev/null +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_win32.c @@ -0,0 +1,183 @@ +/* env_win32.c */ + +/* Copyright 2009-2012 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Networking and other niceties for WIN32. */ +#include "env.h" +#include "mongo.h" +#include <string.h> + +#ifdef _MSC_VER +#include <ws2tcpip.h> // send,recv,socklen_t etc +#include <wspiapi.h> // addrinfo +#else +#include <windows.h> +#include <winsock.h> +typedef int socklen_t; +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif + +static void mongo_clear_errors( mongo *conn ) { + conn->err = 0; + memset( conn->errstr, 0, MONGO_ERR_LEN ); +} + +int mongo_env_close_socket( int socket ) { + return closesocket( socket ); +} + +int mongo_env_write_socket( mongo *conn, const void *buf, int len ) { + const char *cbuf = buf; + int flags = 0; + + while ( len ) { + int sent = send( conn->sock, cbuf, len, flags ); + if ( sent == -1 ) { + __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() ); + conn->connected = 0; + return MONGO_ERROR; + } + cbuf += sent; + len -= sent; + } + + return MONGO_OK; +} + +int mongo_env_read_socket( mongo *conn, void *buf, int len ) { + char *cbuf = buf; + + while ( len ) { + int sent = recv( conn->sock, cbuf, len, 0 ); + if ( sent == 0 || sent == -1 ) { + __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() ); + return MONGO_ERROR; + } + cbuf += sent; + len -= sent; + } + + return MONGO_OK; +} + +int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) { + if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&millis, + sizeof( millis ) ) == -1 ) { + __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.", + WSAGetLastError() ); + return MONGO_ERROR; + } + + if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&millis, + sizeof( millis ) ) == -1 ) { + __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.", + WSAGetLastError() ); + return MONGO_ERROR; + } + + return MONGO_OK; +} + +int mongo_env_socket_connect( mongo *conn, const char *host, int port ) { + char port_str[NI_MAXSERV]; + char errstr[MONGO_ERR_LEN]; + int status; + + struct addrinfo ai_hints; + struct addrinfo *ai_list = NULL; + struct addrinfo *ai_ptr = NULL; + + conn->sock = 0; + conn->connected = 0; + + bson_sprintf( port_str, "%d", port ); + + memset( &ai_hints, 0, sizeof( ai_hints ) ); + ai_hints.ai_family = AF_UNSPEC; + ai_hints.ai_socktype = SOCK_STREAM; + ai_hints.ai_protocol = IPPROTO_TCP; + + status = getaddrinfo( host, port_str, &ai_hints, &ai_list ); + if ( status != 0 ) { + bson_sprintf( errstr, "getaddrinfo failed with error %d", status ); + __mongo_set_error( conn, MONGO_CONN_ADDR_FAIL, errstr, WSAGetLastError() ); + return MONGO_ERROR; + } + + for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) { + conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype, + ai_ptr->ai_protocol ); + + if ( conn->sock < 0 ) { + __mongo_set_error( conn, MONGO_SOCKET_ERROR, "socket() failed", + WSAGetLastError() ); + conn->sock = 0; + continue; + } + + status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen ); + if ( status != 0 ) { + __mongo_set_error( conn, MONGO_SOCKET_ERROR, "connect() failed", + WSAGetLastError() ); + mongo_env_close_socket( conn->sock ); + conn->sock = 0; + continue; + } + + if ( ai_ptr->ai_protocol == IPPROTO_TCP ) { + int flag = 1; + + setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, + ( void * ) &flag, sizeof( flag ) ); + + if ( conn->op_timeout_ms > 0 ) + mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms ); + } + + conn->connected = 1; + break; + } + + freeaddrinfo( ai_list ); + + if ( ! conn->connected ) { + conn->err = MONGO_CONN_FAIL; + return MONGO_ERROR; + } + else { + mongo_clear_errors( conn ); + return MONGO_OK; + } +} + +MONGO_EXPORT int mongo_env_sock_init( void ) { + + WSADATA wsaData; + WORD wVers; + static int called_once; + static int retval; + + if (called_once) return retval; + + called_once = 1; + wVers = MAKEWORD(1, 1); + retval = (WSAStartup(wVers, &wsaData) == 0); + + return retval; +} diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.c index f51b397d3f..9b2d1455ef 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.c @@ -1,6 +1,6 @@ /* gridfs.c */ -/* Copyright 2009-2011 10gen Inc. +/* Copyright 2009-2012 10gen Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,27 @@ #include <string.h> #include <assert.h> +MONGO_EXPORT gridfs* gridfs_create() { + return (gridfs*)bson_malloc(sizeof(gridfs)); +} + +MONGO_EXPORT void gridfs_dispose(gridfs* gfs) { + free(gfs); +} + +MONGO_EXPORT gridfile* gridfile_create() { + return (gridfile*)bson_malloc(sizeof(gridfile)); +} + +MONGO_EXPORT void gridfile_dispose(gridfile* gf) { + free(gf); +} + +MONGO_EXPORT void gridfile_get_descriptor(gridfile* gf, bson* out) { + *out = *gf->meta; +} + + static bson *chunk_new( bson_oid_t id, int chunkNumber, const char *data, int len ) { bson *b = bson_malloc( sizeof( bson ) ); @@ -104,7 +125,7 @@ int gridfs_init( mongo *client, const char *dbname, const char *prefix, return MONGO_OK; } -void gridfs_destroy( gridfs *gfs ) { +MONGO_EXPORT void gridfs_destroy( gridfs *gfs ) { if ( gfs == NULL ) return; if ( gfs->dbname ) bson_free( ( char * )gfs->dbname ); if ( gfs->prefix ) bson_free( ( char * )gfs->prefix ); @@ -120,14 +141,17 @@ static int gridfs_insert_file( gridfs *gfs, const char *name, bson res; bson_iterator it; int result; + int64_t d; /* Check run md5 */ bson_init( &command ); bson_append_oid( &command, "filemd5", &id ); bson_append_string( &command, "root", gfs->prefix ); bson_finish( &command ); - assert( mongo_run_command( gfs->client, gfs->dbname, &command, &res ) == MONGO_OK ); + result = mongo_run_command( gfs->client, gfs->dbname, &command, &res ); bson_destroy( &command ); + if (result != MONGO_OK) + return result; /* Create and insert BSON for file metadata */ bson_init( &ret ); @@ -137,7 +161,8 @@ static int gridfs_insert_file( gridfs *gfs, const char *name, } bson_append_long( &ret, "length", length ); bson_append_int( &ret, "chunkSize", DEFAULT_CHUNK_SIZE ); - bson_append_date( &ret, "uploadDate", ( bson_date_t )1000*time( NULL ) ); + d = ( bson_date_t )1000*time( NULL ); + bson_append_date( &ret, "uploadDate", d); bson_find( &it, &res, "md5" ); bson_append_string( &ret, "md5", bson_iterator_string( &it ) ); bson_destroy( &res ); @@ -151,7 +176,7 @@ static int gridfs_insert_file( gridfs *gfs, const char *name, return result; } -int gridfs_store_buffer( gridfs *gfs, const char *data, +MONGO_EXPORT int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length, const char *remotename, const char *contenttype ) { @@ -163,7 +188,7 @@ int gridfs_store_buffer( gridfs *gfs, const char *data, bson *oChunk; /* Large files Assertion */ - assert( length <= 0xffffffff ); + /* assert( length <= 0xffffffff ); */ /* Generate and append an oid*/ bson_oid_gen( &id ); @@ -183,7 +208,7 @@ int gridfs_store_buffer( gridfs *gfs, const char *data, return gridfs_insert_file( gfs, remotename, id, length, contenttype ); } -void gridfile_writer_init( gridfile *gfile, gridfs *gfs, +MONGO_EXPORT void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name, const char *content_type ) { gfile->gfs = gfs; @@ -200,7 +225,7 @@ void gridfile_writer_init( gridfile *gfile, gridfs *gfs, strcpy( ( char * )gfile->content_type, content_type ); } -void gridfile_write_buffer( gridfile *gfile, const char *data, +MONGO_EXPORT void gridfile_write_buffer( gridfile *gfile, const char *data, gridfs_offset length ) { int bytes_left = 0; @@ -221,14 +246,13 @@ void gridfile_write_buffer( gridfile *gfile, const char *data, gfile->pending_len += length; } else { /* At least one chunk of data to write */ + chunks_to_write = to_write / DEFAULT_CHUNK_SIZE; + bytes_left = to_write % DEFAULT_CHUNK_SIZE; /* If there's a pending chunk to be written, we need to combine * the buffer provided up to DEFAULT_CHUNK_SIZE. */ if ( gfile->pending_len > 0 ) { - chunks_to_write = to_write / DEFAULT_CHUNK_SIZE; - bytes_left = to_write % DEFAULT_CHUNK_SIZE; - data_partial_len = DEFAULT_CHUNK_SIZE - gfile->pending_len; buffer = ( char * )bson_malloc( DEFAULT_CHUNK_SIZE ); memcpy( buffer, gfile->pending_data, gfile->pending_len ); @@ -270,7 +294,7 @@ void gridfile_write_buffer( gridfile *gfile, const char *data, } } -int gridfile_writer_done( gridfile *gfile ) { +MONGO_EXPORT int gridfile_writer_done( gridfile *gfile ) { /* write any remaining pending chunk data. * pending data will always take up less than one chunk */ @@ -307,8 +331,11 @@ int gridfs_store_file( gridfs *gfs, const char *filename, /* Open the file and the correct stream */ if ( strcmp( filename, "-" ) == 0 ) fd = stdin; - else fd = fopen( filename, "rb" ); - assert( fd != NULL ); /* No such file */ + else { + fd = fopen( filename, "rb" ); + if (fd == NULL) + return MONGO_ERROR; + } /* Generate and append an oid*/ bson_oid_gen( &id ); @@ -339,7 +366,7 @@ int gridfs_store_file( gridfs *gfs, const char *filename, return gridfs_insert_file( gfs, remotename, id, length, contenttype ); } -void gridfs_remove_filename( gridfs *gfs, const char *filename ) { +MONGO_EXPORT void gridfs_remove_filename( gridfs *gfs, const char *filename ) { bson query; mongo_cursor *files; bson file; @@ -433,7 +460,7 @@ int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile ) return MONGO_OK; } -void gridfile_destroy( gridfile *gfile ) +MONGO_EXPORT void gridfile_destroy( gridfile *gfile ) { bson_destroy( gfile->meta ); @@ -444,21 +471,21 @@ bson_bool_t gridfile_exists( gridfile *gfile ) { return ( bson_bool_t )( gfile != NULL || gfile->meta == NULL ); } -const char *gridfile_get_filename( gridfile *gfile ) { +MONGO_EXPORT const char *gridfile_get_filename( gridfile *gfile ) { bson_iterator it; bson_find( &it, gfile->meta, "filename" ); return bson_iterator_string( &it ); } -int gridfile_get_chunksize( gridfile *gfile ) { +MONGO_EXPORT int gridfile_get_chunksize( gridfile *gfile ) { bson_iterator it; bson_find( &it, gfile->meta, "chunkSize" ); return bson_iterator_int( &it ); } -gridfs_offset gridfile_get_contentlength( gridfile *gfile ) { +MONGO_EXPORT gridfs_offset gridfile_get_contentlength( gridfile *gfile ) { bson_iterator it; bson_find( &it, gfile->meta, "length" ); @@ -469,7 +496,7 @@ gridfs_offset gridfile_get_contentlength( gridfile *gfile ) { return ( gridfs_offset )bson_iterator_long( &it ); } -const char *gridfile_get_contenttype( gridfile *gfile ) { +MONGO_EXPORT const char *gridfile_get_contenttype( gridfile *gfile ) { bson_iterator it; if ( bson_find( &it, gfile->meta, "contentType" ) ) @@ -477,14 +504,14 @@ const char *gridfile_get_contenttype( gridfile *gfile ) { else return NULL; } -bson_date_t gridfile_get_uploaddate( gridfile *gfile ) { +MONGO_EXPORT bson_date_t gridfile_get_uploaddate( gridfile *gfile ) { bson_iterator it; bson_find( &it, gfile->meta, "uploadDate" ); return bson_iterator_date( &it ); } -const char *gridfile_get_md5( gridfile *gfile ) { +MONGO_EXPORT const char *gridfile_get_md5( gridfile *gfile ) { bson_iterator it; bson_find( &it, gfile->meta, "md5" ); @@ -505,20 +532,16 @@ bson_bool_t gridfile_get_boolean( gridfile *gfile, const char *name ) { return bson_iterator_bool( &it ); } -bson gridfile_get_metadata( gridfile *gfile ) { - bson sub; +MONGO_EXPORT void gridfile_get_metadata( gridfile *gfile, bson* out ) { bson_iterator it; - if ( bson_find( &it, gfile->meta, "metadata" ) ) { - bson_iterator_subobject( &it, &sub ); - return sub; - } else { - bson_empty( &sub ); - return sub; - } + if ( bson_find( &it, gfile->meta, "metadata" ) ) + bson_iterator_subobject( &it, out ); + else + bson_empty( out ); } -int gridfile_get_numchunks( gridfile *gfile ) { +MONGO_EXPORT int gridfile_get_numchunks( gridfile *gfile ) { bson_iterator it; gridfs_offset length; gridfs_offset chunkSize; @@ -539,11 +562,12 @@ int gridfile_get_numchunks( gridfile *gfile ) { : ( int )( numchunks ); } -bson gridfile_get_chunk( gridfile *gfile, int n ) { +MONGO_EXPORT void gridfile_get_chunk( gridfile *gfile, int n, bson* out ) { bson query; - bson out; + bson_iterator it; bson_oid_t id; + int result; bson_init( &query ); bson_find( &it, gfile->meta, "_id" ); @@ -552,15 +576,18 @@ bson gridfile_get_chunk( gridfile *gfile, int n ) { bson_append_int( &query, "n", n ); bson_finish( &query ); - assert( mongo_find_one( gfile->gfs->client, - gfile->gfs->chunks_ns, - &query, NULL, &out ) == MONGO_OK ); - + result = (mongo_find_one(gfile->gfs->client, + gfile->gfs->chunks_ns, + &query, NULL, out ) == MONGO_OK ); bson_destroy( &query ); - return out; + if (!result) { + bson empty; + bson_empty(&empty); + bson_copy(out, &empty); + } } -mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ) { +MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ) { bson_iterator it; bson_oid_t id; bson gte; @@ -613,18 +640,18 @@ gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ) { const int num = gridfile_get_numchunks( gfile ); for ( i=0; i<num; i++ ) { - chunk = gridfile_get_chunk( gfile, i ); + gridfile_get_chunk( gfile, i, &chunk ); bson_find( &it, &chunk, "data" ); len = bson_iterator_bin_len( &it ); data = bson_iterator_bin_data( &it ); - fwrite( data , sizeof( char ), len, stream ); + fwrite( data, sizeof( char ), len, stream ); bson_destroy( &chunk ); } return gridfile_get_contentlength( gfile ); } -gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ) { +MONGO_EXPORT gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ) { mongo_cursor *chunks; bson chunk; @@ -676,7 +703,7 @@ gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ) { return size; } -gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset ) { +MONGO_EXPORT gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset ) { gridfs_offset length; length = gridfile_get_contentlength( gfile ); diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.h index 36595ee341..d313e1afd8 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.h +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.h @@ -4,7 +4,7 @@ * * */ -/* Copyright 2009-2011 10gen Inc. +/* Copyright 2009-2012 10gen Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,8 @@ #include "mongo.h" -#ifndef GRIDFS_INCLUDED -#define GRIDFS_INCLUDED +#ifndef MONGO_GRIDFS_H_ +#define MONGO_GRIDFS_H_ enum {DEFAULT_CHUNK_SIZE = 256 * 1024}; @@ -51,6 +51,12 @@ typedef struct { int pending_len; /**> Length of pending_data buffer */ } gridfile; +MONGO_EXPORT gridfs* gridfs_create(); +MONGO_EXPORT void gridfs_dispose(gridfs* gfs); +MONGO_EXPORT gridfile* gridfile_create(); +MONGO_EXPORT void gridfile_dispose(gridfile* gf); +MONGO_EXPORT void gridfile_get_descriptor(gridfile* gf, bson* out); + /** * Initializes a GridFS object * @param client - db connection @@ -60,7 +66,7 @@ typedef struct { * * @return - MONGO_OK or MONGO_ERROR. */ -int gridfs_init( mongo *client, const char *dbname, +MONGO_EXPORT int gridfs_init( mongo *client, const char *dbname, const char *prefix, gridfs *gfs ); /** @@ -69,7 +75,7 @@ int gridfs_init( mongo *client, const char *dbname, * * @param gfs a grid */ -void gridfs_destroy( gridfs *gfs ); +MONGO_EXPORT void gridfs_destroy( gridfs *gfs ); /** * Initializes a gridfile for writing incrementally with gridfs_write_buffer. @@ -77,7 +83,7 @@ void gridfs_destroy( gridfs *gfs ); * When done, you must call gridfs_writer_done to save the file metadata. * */ -void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name, +MONGO_EXPORT void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name, const char *content_type ); /** @@ -86,7 +92,7 @@ void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name * stream to a GridFS file. When finished, be sure to call gridfs_writer_done. * */ -void gridfile_write_buffer( gridfile *gfile, const char *data, +MONGO_EXPORT void gridfile_write_buffer( gridfile *gfile, const char *data, gridfs_offset length ); /** @@ -96,7 +102,7 @@ void gridfile_write_buffer( gridfile *gfile, const char *data, * * @return - MONGO_OK or MONGO_ERROR. */ -int gridfile_writer_done( gridfile *gfile ); +MONGO_EXPORT int gridfile_writer_done( gridfile *gfile ); /** * Store a buffer as a GridFS file. @@ -108,7 +114,7 @@ int gridfile_writer_done( gridfile *gfile ); * * @return - MONGO_OK or MONGO_ERROR. */ -int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length, +MONGO_EXPORT int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length, const char *remotename, const char *contenttype ); @@ -121,7 +127,7 @@ int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length, * * @return - MONGO_OK or MONGO_ERROR. */ -int gridfs_store_file( gridfs *gfs, const char *filename, +MONGO_EXPORT int gridfs_store_file( gridfs *gfs, const char *filename, const char *remotename, const char *contenttype ); /** @@ -129,7 +135,7 @@ int gridfs_store_file( gridfs *gfs, const char *filename, * @param gfs - the working GridFS * @param filename - the filename of the file/s to be removed */ -void gridfs_remove_filename( gridfs *gfs, const char *filename ); +MONGO_EXPORT void gridfs_remove_filename( gridfs *gfs, const char *filename ); /** * Find the first file matching the provided query within the @@ -141,7 +147,7 @@ void gridfs_remove_filename( gridfs *gfs, const char *filename ); * * @return MONGO_OK if successful, MONGO_ERROR otherwise */ -int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile ); +MONGO_EXPORT int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile ); /** * Find the first file referenced by filename within the GridFS @@ -152,7 +158,7 @@ int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile ); * * @return MONGO_OK or MONGO_ERROR. */ -int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile ); +MONGO_EXPORT int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile ); /** * Initializes a GridFile containing the GridFS and file bson @@ -162,20 +168,20 @@ int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile ); * * @return - MONGO_OK or MONGO_ERROR. */ -int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile ); +MONGO_EXPORT int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile ); /** * Destroys the GridFile * * @param oGridFIle - the GridFile being destroyed */ -void gridfile_destroy( gridfile *gfile ); +MONGO_EXPORT void gridfile_destroy( gridfile *gfile ); /** * Returns whether or not the GridFile exists * @param gfile - the GridFile being examined */ -bson_bool_t gridfile_exists( gridfile *gfile ); +MONGO_EXPORT bson_bool_t gridfile_exists( gridfile *gfile ); /** * Returns the filename of GridFile @@ -183,7 +189,7 @@ bson_bool_t gridfile_exists( gridfile *gfile ); * * @return - the filename of the Gridfile */ -const char *gridfile_get_filename( gridfile *gfile ); +MONGO_EXPORT const char *gridfile_get_filename( gridfile *gfile ); /** * Returns the size of the chunks of the GridFile @@ -191,7 +197,7 @@ const char *gridfile_get_filename( gridfile *gfile ); * * @return - the size of the chunks of the Gridfile */ -int gridfile_get_chunksize( gridfile *gfile ); +MONGO_EXPORT int gridfile_get_chunksize( gridfile *gfile ); /** * Returns the length of GridFile's data @@ -200,7 +206,7 @@ int gridfile_get_chunksize( gridfile *gfile ); * * @return - the length of the Gridfile's data */ -gridfs_offset gridfile_get_contentlength( gridfile *gfile ); +MONGO_EXPORT gridfs_offset gridfile_get_contentlength( gridfile *gfile ); /** * Returns the MIME type of the GridFile @@ -210,7 +216,7 @@ gridfs_offset gridfile_get_contentlength( gridfile *gfile ); * @return - the MIME type of the Gridfile * (NULL if no type specified) */ -const char *gridfile_get_contenttype( gridfile *gfile ); +MONGO_EXPORT const char *gridfile_get_contenttype( gridfile *gfile ); /** * Returns the upload date of GridFile @@ -219,7 +225,7 @@ const char *gridfile_get_contenttype( gridfile *gfile ); * * @return - the upload date of the Gridfile */ -bson_date_t gridfile_get_uploaddate( gridfile *gfile ); +MONGO_EXPORT bson_date_t gridfile_get_uploaddate( gridfile *gfile ); /** * Returns the MD5 of GridFile @@ -228,7 +234,7 @@ bson_date_t gridfile_get_uploaddate( gridfile *gfile ); * * @return - the MD5 of the Gridfile */ -const char *gridfile_get_md5( gridfile *gfile ); +MONGO_EXPORT const char *gridfile_get_md5( gridfile *gfile ); /** * Returns the field in GridFile specified by name @@ -260,7 +266,7 @@ bson_bool_t gridfile_get_boolean( gridfile *gfile, * @return - the metadata of the Gridfile in a bson object * (an empty bson is returned if none exists) */ -bson gridfile_get_metadata( gridfile *gfile ); +MONGO_EXPORT void gridfile_get_metadata( gridfile *gfile, bson* out ); /** * Returns the number of chunks in the GridFile @@ -268,7 +274,7 @@ bson gridfile_get_metadata( gridfile *gfile ); * * @return - the number of chunks in the Gridfile */ -int gridfile_get_numchunks( gridfile *gfile ); +MONGO_EXPORT int gridfile_get_numchunks( gridfile *gfile ); /** * Returns chunk n of GridFile @@ -276,7 +282,7 @@ int gridfile_get_numchunks( gridfile *gfile ); * * @return - the nth chunk of the Gridfile */ -bson gridfile_get_chunk( gridfile *gfile, int n ); +MONGO_EXPORT void gridfile_get_chunk( gridfile *gfile, int n, bson* out ); /** * Returns a mongo_cursor of *size* chunks starting with chunk *start* @@ -287,7 +293,7 @@ bson gridfile_get_chunk( gridfile *gfile, int n ); * * @return - mongo_cursor of the chunks (must be destroyed after use) */ -mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ); +MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ); /** * Writes the GridFile to a stream @@ -295,7 +301,7 @@ mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ); * @param gfile - the working GridFile * @param stream - the file stream to write to */ -gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ); +MONGO_EXPORT gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ); /** * Reads length bytes from the GridFile to a buffer @@ -309,7 +315,7 @@ gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ); * * @return - the number of bytes read */ -gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ); +MONGO_EXPORT gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ); /** * Updates the position in the file @@ -321,6 +327,6 @@ gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ); * * @return - resulting offset location */ -gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset ); +MONGO_EXPORT gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset ); #endif diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.c index d1c1e3ab0b..68edd29513 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.c @@ -309,7 +309,7 @@ mongo_md5_process(mongo_md5_state_t *pms, const mongo_md5_byte_t *data /*[64]*/) pms->abcd[3] += d; } -void +MONGO_EXPORT void mongo_md5_init(mongo_md5_state_t *pms) { pms->count[0] = pms->count[1] = 0; @@ -319,7 +319,7 @@ mongo_md5_init(mongo_md5_state_t *pms) pms->abcd[3] = 0x10325476; } -void +MONGO_EXPORT void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes) { const mongo_md5_byte_t *p = data; @@ -357,7 +357,7 @@ mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbyte memcpy(pms->buf, p, left); } -void +MONGO_EXPORT void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]) { static const mongo_md5_byte_t pad[64] = { diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.h index 540da3a584..342b6a7307 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.h +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.h @@ -47,8 +47,8 @@ 1999-05-03 lpd Original version. */ -#ifndef md5_INCLUDED -# define md5_INCLUDED +#ifndef MONGO_MD5_H_ +#define MONGO_MD5_H_ /* * This package supports both compile-time and run-time determination of CPU @@ -59,6 +59,7 @@ * run on either big- or little-endian CPUs, but will run slightly less * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. */ +#include "bson.h" typedef unsigned char mongo_md5_byte_t; /* 8-bit byte */ typedef unsigned int mongo_md5_word_t; /* 32-bit word */ @@ -75,17 +76,17 @@ extern "C" { #endif - /* Initialize the algorithm. */ - void mongo_md5_init(mongo_md5_state_t *pms); +/* Initialize the algorithm. */ +MONGO_EXPORT void mongo_md5_init(mongo_md5_state_t *pms); - /* Append a string to the message. */ - void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes); +/* Append a string to the message. */ +MONGO_EXPORT void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes); - /* Finish the message and return the digest. */ - void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]); +/* Finish the message and return the digest. */ +MONGO_EXPORT void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]); #ifdef __cplusplus } /* end extern "C" */ #endif -#endif /* md5_INCLUDED */ +#endif /* MONGO_MD5_H_ */ diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.c index 2090e74312..eb16392297 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.c @@ -1,6 +1,6 @@ /* mongo.c */ -/* Copyright 2009-2011 10gen Inc. +/* Copyright 2009-2012 10gen Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +17,235 @@ #include "mongo.h" #include "md5.h" +#include "env.h" #include <stdlib.h> #include <stdio.h> #include <string.h> #include <stdlib.h> -#ifdef _USE_LINUX_SYSTEM -#include "platform/linux/net.h" -#elif defined _USE_CUSTOM_SYSTEM -#include "platform/custom/net.h" -#else -#include "net.h" -#endif +MONGO_EXPORT mongo* mongo_create() { + return (mongo*)bson_malloc(sizeof(mongo)); +} + + +MONGO_EXPORT void mongo_dispose(mongo* conn) { + free(conn); +} + +MONGO_EXPORT int mongo_get_err(mongo* conn) { + return conn->err; +} + + +MONGO_EXPORT int mongo_is_connected(mongo* conn) { + return conn->connected != 0; +} + + +MONGO_EXPORT int mongo_get_op_timeout(mongo* conn) { + return conn->op_timeout_ms; +} + + +const char* _get_host_port(mongo_host_port* hp) { + static char _hp[sizeof(hp->host)+12]; + bson_sprintf(_hp, "%s:%d", hp->host, hp->port); + return _hp; +} + + +MONGO_EXPORT const char* mongo_get_primary(mongo* conn) { + mongo* conn_ = (mongo*)conn; + return _get_host_port(conn_->primary); +} + + +MONGO_EXPORT int mongo_get_socket(mongo* conn) { + mongo* conn_ = (mongo*)conn; + return conn_->sock; +} + + +MONGO_EXPORT int mongo_get_host_count(mongo* conn) { + mongo_replset* r = conn->replset; + mongo_host_port* hp; + int count = 0; + if (!r) return 0; + for (hp = r->hosts; hp; hp = hp->next) + ++count; + return count; +} + + +MONGO_EXPORT const char* mongo_get_host(mongo* conn, int i) { + mongo_replset* r = conn->replset; + mongo_host_port* hp; + int count = 0; + if (!r) return 0; + for (hp = r->hosts; hp; hp = hp->next) { + if (count == i) + return _get_host_port(hp); + ++count; + } + return 0; +} + + +MONGO_EXPORT mongo_cursor* mongo_cursor_create() { + return (mongo_cursor*)bson_malloc(sizeof(mongo_cursor)); +} + + +MONGO_EXPORT void mongo_cursor_dispose(mongo_cursor* cursor) { + free(cursor); +} + + +MONGO_EXPORT int mongo_get_server_err(mongo* conn) { + return conn->lasterrcode; +} + + +MONGO_EXPORT const char* mongo_get_server_err_string(mongo* conn) { + return conn->lasterrstr; +} + +MONGO_EXPORT void __mongo_set_error( mongo *conn, mongo_error_t err, const char *str, + int errcode ) { + int errstr_size, str_size; + + conn->err = err; + conn->errcode = errcode; + + if( str ) { + str_size = strlen( str ) + 1; + errstr_size = str_size > MONGO_ERR_LEN ? MONGO_ERR_LEN : str_size; + memcpy( conn->errstr, str, errstr_size ); + conn->errstr[errstr_size] = '\0'; + } +} + +MONGO_EXPORT void mongo_clear_errors( mongo *conn ) { + conn->err = 0; + conn->errcode = 0; + conn->lasterrcode = 0; + memset( conn->errstr, 0, MONGO_ERR_LEN ); + memset( conn->lasterrstr, 0, MONGO_ERR_LEN ); +} + +MONGO_EXPORT int mongo_validate_ns( mongo *conn, const char *ns ) { + char *last = NULL; + char *current = NULL; + const char *db_name = ns; + char *collection_name = NULL; + char errmsg[64]; + int ns_len = 0; + + /* If the first character is a '.', fail. */ + if( *ns == '.' ) { + __mongo_set_error( conn, MONGO_NS_INVALID, "ns cannot start with a '.'.", 0 ); + return MONGO_ERROR; + } + + /* Find the division between database and collection names. */ + for( current = (char *)ns; *current != '\0'; current++ ) { + if( *current == '.' ) { + current++; + break; + } + } + + /* Fail because the ns doesn't contain a '.' + * or the collection part starts with a dot. */ + if( *current == '\0' || *current == '.' ) { + __mongo_set_error( conn, MONGO_NS_INVALID, "ns cannot start with a '.'.", 0 ); + return MONGO_ERROR; + } + + /* Fail if collection length is 0. */ + if( *(current + 1) == '\0' ) { + __mongo_set_error( conn, MONGO_NS_INVALID, "Collection name missing.", 0 ); + return MONGO_ERROR; + } + + + /* Point to the beginning of the collection name. */ + collection_name = current; + + /* Ensure that the database name is greater than one char.*/ + if( collection_name - 1 == db_name ) { + __mongo_set_error( conn, MONGO_NS_INVALID, "Database name missing.", 0 ); + return MONGO_ERROR; + } + + /* Go back and validate the database name. */ + for( current = (char *)db_name; *current != '.'; current++ ) { + switch( *current ) { + case ' ': + case '$': + case '/': + case '\\': + __mongo_set_error( conn, MONGO_NS_INVALID, + "Database name may not contain ' ', '$', '/', or '\\'", 0 ); + return MONGO_ERROR; + default: + break; + } + + ns_len++; + } + + /* Add one to the length for the '.' character. */ + ns_len++; + + /* Now validate the collection name. */ + for( current = collection_name; *current != '\0'; current++ ) { + + /* Cannot have two consecutive dots. */ + if( last && *last == '.' && *current == '.' ) { + __mongo_set_error( conn, MONGO_NS_INVALID, + "Collection may not contain two consecutive '.'", 0 ); + return MONGO_ERROR; + } + + /* Cannot contain a '$' */ + if( *current == '$' ) { + __mongo_set_error( conn, MONGO_NS_INVALID, + "Collection may not contain '$'", 0 ); + return MONGO_ERROR; + } + + last = current; + ns_len++; + } + + if( ns_len > 128 ) { + bson_sprintf( errmsg, "Namespace too long; has %d but must <= 128.", + ns_len ); + __mongo_set_error( conn, MONGO_NS_INVALID, errmsg, 0 ); + return MONGO_ERROR; + } + + /* Cannot end with a '.' */ + if( *(current - 1) == '.' ) { + __mongo_set_error( conn, MONGO_NS_INVALID, + "Collection may not end with '.'", 0 ); + return MONGO_ERROR; + } + + return MONGO_OK; +} + +static void mongo_set_last_error( mongo *conn, bson_iterator *it, bson *obj ) { + int result_len = bson_iterator_string_len( it ); + const char *result_string = bson_iterator_string( it ); + int len = result_len < MONGO_ERR_LEN ? result_len : MONGO_ERR_LEN; + memcpy( conn->lasterrstr, result_string, len ); + + if( bson_find( it, obj, "code" ) != BSON_NULL ) + conn->lasterrcode = bson_iterator_int( it ); +} static const int ZERO = 0; static const int ONE = 1; @@ -57,13 +273,13 @@ int mongo_message_send( mongo *conn, mongo_message *mm ) { bson_little_endian32( &head.responseTo, &mm->head.responseTo ); bson_little_endian32( &head.op, &mm->head.op ); - res = mongo_write_socket( conn, &head, sizeof( head ) ); + res = mongo_env_write_socket( conn, &head, sizeof( head ) ); if( res != MONGO_OK ) { bson_free( mm ); return res; } - res = mongo_write_socket( conn, &mm->data, mm->head.len - sizeof( head ) ); + res = mongo_env_write_socket( conn, &mm->data, mm->head.len - sizeof( head ) ); if( res != MONGO_OK ) { bson_free( mm ); return res; @@ -80,8 +296,8 @@ int mongo_read_response( mongo *conn, mongo_reply **reply ) { unsigned int len; int res; - mongo_read_socket( conn, &head, sizeof( head ) ); - mongo_read_socket( conn, &fields, sizeof( fields ) ); + mongo_env_read_socket( conn, &head, sizeof( head ) ); + mongo_env_read_socket( conn, &fields, sizeof( fields ) ); bson_little_endian32( &len, &head.len ); @@ -100,7 +316,7 @@ int mongo_read_response( mongo *conn, mongo_reply **reply ) { bson_little_endian32( &out->fields.start, &fields.start ); bson_little_endian32( &out->fields.num, &fields.num ); - res = mongo_read_socket( conn, &out->objs, len-sizeof( head )-sizeof( fields ) ); + res = mongo_env_read_socket( conn, &out->objs, len-sizeof( head )-sizeof( fields ) ); if( res != MONGO_OK ) { bson_free( out ); return res; @@ -133,12 +349,17 @@ static int mongo_check_is_master( mongo *conn ) { bson out; bson_iterator it; bson_bool_t ismaster = 0; + int max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE; out.data = NULL; if ( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) { if( bson_find( &it, &out, "ismaster" ) ) ismaster = bson_iterator_bool( &it ); + if( bson_find( &it, &out, "maxBsonObjectSize" ) ) { + max_bson_size = bson_iterator_int( &it ); + } + conn->max_bson_size = max_bson_size; } else { return MONGO_ERROR; } @@ -153,25 +374,25 @@ static int mongo_check_is_master( mongo *conn ) { } } -void mongo_init( mongo *conn ) { - conn->replset = NULL; - conn->err = 0; - conn->errstr = NULL; - conn->lasterrcode = 0; - conn->lasterrstr = NULL; - - conn->conn_timeout_ms = 0; - conn->op_timeout_ms = 0; +MONGO_EXPORT void mongo_init_sockets( void ) { + mongo_env_sock_init(); } -int mongo_connect( mongo *conn , const char *host, int port ) { + +MONGO_EXPORT void mongo_init( mongo *conn ) { + memset( conn, 0, sizeof( mongo ) ); + conn->max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE; +} + +MONGO_EXPORT int mongo_connect( mongo *conn , const char *host, int port ) { + mongo_init( conn ); + conn->primary = bson_malloc( sizeof( mongo_host_port ) ); strncpy( conn->primary->host, host, strlen( host ) + 1 ); conn->primary->port = port; conn->primary->next = NULL; - mongo_init( conn ); - if( mongo_socket_connect( conn, host, port ) != MONGO_OK ) + if( mongo_env_socket_connect( conn, host, port ) != MONGO_OK ) return MONGO_ERROR; if( mongo_check_is_master( conn ) != MONGO_OK ) @@ -180,7 +401,7 @@ int mongo_connect( mongo *conn , const char *host, int port ) { return MONGO_OK; } -void mongo_replset_init( mongo *conn, const char *name ) { +MONGO_EXPORT void mongo_replset_init( mongo *conn, const char *name ) { mongo_init( conn ); conn->replset = bson_malloc( sizeof( mongo_replset ) ); @@ -222,7 +443,7 @@ static void mongo_replset_free_list( mongo_host_port **list ) { *list = NULL; } -void mongo_replset_add_seed( mongo *conn, const char *host, int port ) { +MONGO_EXPORT void mongo_replset_add_seed( mongo *conn, const char *host, int port ) { mongo_replset_add_node( &conn->replset->seeds, host, port ); } @@ -291,7 +512,7 @@ static void mongo_replset_check_seed( mongo *conn ) { bson_destroy( &out ); bson_destroy( &hosts ); - mongo_close_socket( conn->sock ); + mongo_env_close_socket( conn->sock ); conn->sock = 0; conn->connected = 0; @@ -306,6 +527,7 @@ static int mongo_replset_check_host( mongo *conn ) { bson_iterator it; bson_bool_t ismaster = 0; const char *set_name; + int max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE; out.data = NULL; @@ -313,6 +535,10 @@ static int mongo_replset_check_host( mongo *conn ) { if( bson_find( &it, &out, "ismaster" ) ) ismaster = bson_iterator_bool( &it ); + if( bson_find( &it, &out, "maxBsonObjectSize" ) ) + max_bson_size = bson_iterator_int( &it ); + conn->max_bson_size = max_bson_size; + if( bson_find( &it, &out, "setName" ) ) { set_name = bson_iterator_string( &it ); if( strcmp( set_name, conn->replset->name ) != 0 ) { @@ -328,13 +554,13 @@ static int mongo_replset_check_host( mongo *conn ) { if( ismaster ) { conn->replset->primary_connected = 1; } else { - mongo_close_socket( conn->sock ); + mongo_env_close_socket( conn->sock ); } return MONGO_OK; } -int mongo_replset_connect( mongo *conn ) { +MONGO_EXPORT int mongo_replset_connect( mongo *conn ) { int res = 0; mongo_host_port *node; @@ -347,15 +573,12 @@ int mongo_replset_connect( mongo *conn ) { */ node = conn->replset->seeds; while( node != NULL ) { - res = mongo_socket_connect( conn, ( const char * )&node->host, node->port ); - if( res != MONGO_OK ) - return MONGO_ERROR; - - mongo_replset_check_seed( conn ); - - if( conn->replset->hosts ) - break; - + res = mongo_env_socket_connect( conn, ( const char * )&node->host, node->port ); + if( res == MONGO_OK ) { + mongo_replset_check_seed( conn ); + if( conn->replset->hosts ) + break; + } node = node->next; } @@ -367,19 +590,22 @@ int mongo_replset_connect( mongo *conn ) { node = conn->replset->hosts; while( node != NULL ) { - res = mongo_socket_connect( conn, ( const char * )&node->host, node->port ); + res = mongo_env_socket_connect( conn, ( const char * )&node->host, node->port ); if( res == MONGO_OK ) { if( mongo_replset_check_host( conn ) != MONGO_OK ) return MONGO_ERROR; /* Primary found, so return. */ - else if( conn->replset->primary_connected ) + else if( conn->replset->primary_connected ) { + strncpy( conn->primary->host, node->host, strlen( node->host ) + 1 ); + conn->primary->port = node->port; return MONGO_OK; + } /* No primary, so close the connection. */ else { - mongo_close_socket( conn->sock ); + mongo_env_close_socket( conn->sock ); conn->sock = 0; conn->connected = 0; } @@ -394,15 +620,15 @@ int mongo_replset_connect( mongo *conn ) { return MONGO_ERROR; } -int mongo_set_op_timeout( mongo *conn, int millis ) { +MONGO_EXPORT int mongo_set_op_timeout( mongo *conn, int millis ) { conn->op_timeout_ms = millis; if( conn->sock && conn->connected ) - mongo_set_socket_op_timeout( conn, millis ); + mongo_env_set_socket_op_timeout( conn, millis ); return MONGO_OK; } -int mongo_reconnect( mongo *conn ) { +MONGO_EXPORT int mongo_reconnect( mongo *conn ) { int res; mongo_disconnect( conn ); @@ -413,10 +639,10 @@ int mongo_reconnect( mongo *conn ) { res = mongo_replset_connect( conn ); return res; } else - return mongo_socket_connect( conn, conn->primary->host, conn->primary->port ); + return mongo_env_socket_connect( conn, conn->primary->host, conn->primary->port ); } -int mongo_check_connection( mongo *conn ) { +MONGO_EXPORT int mongo_check_connection( mongo *conn ) { if( ! conn->connected ) return MONGO_ERROR; @@ -426,7 +652,7 @@ int mongo_check_connection( mongo *conn ) { return MONGO_ERROR; } -void mongo_disconnect( mongo *conn ) { +MONGO_EXPORT void mongo_disconnect( mongo *conn ) { if( ! conn->connected ) return; @@ -436,13 +662,13 @@ void mongo_disconnect( mongo *conn ) { conn->replset->hosts = NULL; } - mongo_close_socket( conn->sock ); + mongo_env_close_socket( conn->sock ); conn->sock = 0; conn->connected = 0; } -void mongo_destroy( mongo *conn ) { +MONGO_EXPORT void mongo_destroy( mongo *conn ) { mongo_disconnect( conn ); if( conn->replset ) { @@ -454,17 +680,20 @@ void mongo_destroy( mongo *conn ) { } bson_free( conn->primary ); - bson_free( conn->errstr ); - bson_free( conn->lasterrstr ); - conn->err = 0; - conn->errstr = NULL; - conn->lasterrcode = 0; - conn->lasterrstr = NULL; + mongo_clear_errors( conn ); } /* Determine whether this BSON object is valid for the given operation. */ -static int mongo_bson_valid( mongo *conn, bson *bson, int write ) { +static int mongo_bson_valid( mongo *conn, const bson *bson, int write ) { + int size; + + size = bson_size( bson ); + if( size > conn->max_bson_size ) { + conn->err = MONGO_BSON_TOO_LARGE; + return MONGO_ERROR; + } + if( ! bson->finished ) { conn->err = MONGO_BSON_NOT_FINISHED; return MONGO_ERROR; @@ -486,20 +715,21 @@ static int mongo_bson_valid( mongo *conn, bson *bson, int write ) { } conn->err = 0; - conn->errstr = NULL; return MONGO_OK; } /* Determine whether this BSON object is valid for the given operation. */ -static int mongo_cursor_bson_valid( mongo_cursor *cursor, bson *bson ) { +static int mongo_cursor_bson_valid( mongo_cursor *cursor, const bson *bson ) { if( ! bson->finished ) { - cursor->err = MONGO_BSON_NOT_FINISHED; + cursor->err = MONGO_CURSOR_BSON_ERROR; + cursor->conn->err = MONGO_BSON_NOT_FINISHED; return MONGO_ERROR; } if( bson->err & BSON_NOT_UTF8 ) { - cursor->err = MONGO_BSON_INVALID; + cursor->err = MONGO_CURSOR_BSON_ERROR; + cursor->conn->err = MONGO_BSON_INVALID; return MONGO_ERROR; } @@ -508,13 +738,17 @@ static int mongo_cursor_bson_valid( mongo_cursor *cursor, bson *bson ) { /* MongoDB CRUD API */ -int mongo_insert_batch( mongo *conn, const char *ns, - bson **bsons, int count ) { +MONGO_EXPORT int mongo_insert_batch( mongo *conn, const char *ns, + const bson **bsons, int count ) { - int size = 16 + 4 + strlen( ns ) + 1; - int i; mongo_message *mm; + int i; char *data; + int overhead = 16 + 4 + strlen( ns ) + 1; + int size = overhead; + + if( mongo_validate_ns( conn, ns ) != MONGO_OK ) + return MONGO_ERROR; for( i=0; i<count; i++ ) { size += bson_size( bsons[i] ); @@ -522,6 +756,11 @@ int mongo_insert_batch( mongo *conn, const char *ns, return MONGO_ERROR; } + if( ( size - overhead ) > conn->max_bson_size ) { + conn->err = MONGO_BSON_TOO_LARGE; + return MONGO_ERROR; + } + mm = mongo_message_create( size , 0 , 0 , MONGO_OP_INSERT ); data = &mm->data; @@ -535,11 +774,14 @@ int mongo_insert_batch( mongo *conn, const char *ns, return mongo_message_send( conn, mm ); } -int mongo_insert( mongo *conn , const char *ns , bson *bson ) { +MONGO_EXPORT int mongo_insert( mongo *conn , const char *ns , const bson *bson ) { char *data; mongo_message *mm; + if( mongo_validate_ns( conn, ns ) != MONGO_OK ) + return MONGO_ERROR; + /* Make sure that BSON is valid for insert. */ if( mongo_bson_valid( conn, bson, 1 ) != MONGO_OK ) { return MONGO_ERROR; @@ -559,7 +801,7 @@ int mongo_insert( mongo *conn , const char *ns , bson *bson ) { return mongo_message_send( conn, mm ); } -int mongo_update( mongo *conn, const char *ns, const bson *cond, +MONGO_EXPORT int mongo_update( mongo *conn, const char *ns, const bson *cond, const bson *op, int flags ) { char *data; @@ -590,14 +832,9 @@ int mongo_update( mongo *conn, const char *ns, const bson *cond, return mongo_message_send( conn, mm ); } -int mongo_remove( mongo *conn, const char *ns, const bson *cond ) { +MONGO_EXPORT int mongo_remove( mongo *conn, const char *ns, const bson *cond ) { char *data; - mongo_message *mm = mongo_message_create( 16 /* header */ - + 4 /* ZERO */ - + strlen( ns ) + 1 - + 4 /* ZERO */ - + bson_size( cond ) - , 0 , 0 , MONGO_OP_DELETE ); + mongo_message *mm; /* Make sure that the BSON is valid UTF-8. * TODO: decide whether to check cond as well. @@ -606,6 +843,13 @@ int mongo_remove( mongo *conn, const char *ns, const bson *cond ) { return MONGO_ERROR; } + mm = mongo_message_create( 16 /* header */ + + 4 /* ZERO */ + + strlen( ns ) + 1 + + 4 /* ZERO */ + + bson_size( cond ) + , 0 , 0 , MONGO_OP_DELETE ); + data = &mm->data; data = mongo_data_append32( data, &ZERO ); data = mongo_data_append( data, ns, strlen( ns ) + 1 ); @@ -621,6 +865,11 @@ static int mongo_cursor_op_query( mongo_cursor *cursor ) { bson empty; char *data; mongo_message *mm; + bson temp; + bson_iterator it; + + /* Clear any errors. */ + mongo_clear_errors( cursor->conn ); /* Set up default values for query and fields, if necessary. */ if( ! cursor->query ) @@ -662,6 +911,15 @@ static int mongo_cursor_op_query( mongo_cursor *cursor ) { return MONGO_ERROR; } + if( cursor->reply->fields.num == 1 ) { + bson_init_data( &temp, &cursor->reply->objs ); + if( bson_find( &it, &temp, "$err" ) ) { + mongo_set_last_error( cursor->conn, &it, &temp ); + cursor->err = MONGO_CURSOR_QUERY_FAIL; + return MONGO_ERROR; + } + } + cursor->seen += cursor->reply->fields.num; cursor->flags |= MONGO_CURSOR_QUERY_SENT; return MONGO_OK; @@ -719,8 +977,8 @@ static int mongo_cursor_get_more( mongo_cursor *cursor ) { } } -mongo_cursor *mongo_find( mongo *conn, const char *ns, bson *query, - bson *fields, int limit, int skip, int options ) { +MONGO_EXPORT mongo_cursor *mongo_find( mongo *conn, const char *ns, const bson *query, + const bson *fields, int limit, int skip, int options ) { mongo_cursor *cursor = ( mongo_cursor * )bson_malloc( sizeof( mongo_cursor ) ); mongo_cursor_init( cursor, conn, ns ); @@ -740,13 +998,20 @@ mongo_cursor *mongo_find( mongo *conn, const char *ns, bson *query, } } -int mongo_find_one( mongo *conn, const char *ns, bson *query, - bson *fields, bson *out ) { +MONGO_EXPORT int mongo_find_one( mongo *conn, const char *ns, const bson *query, + const bson *fields, bson *out ) { - mongo_cursor *cursor = mongo_find( conn, ns, query, fields, 1, 0, 0 ); + mongo_cursor cursor[1]; + mongo_cursor_init( cursor, conn, ns ); + mongo_cursor_set_query( cursor, query ); + mongo_cursor_set_fields( cursor, fields ); + mongo_cursor_set_limit( cursor, 1 ); - if ( cursor && mongo_cursor_next( cursor ) == MONGO_OK ) { - bson_copy_basic( out, &cursor->current ); + if ( mongo_cursor_next( cursor ) == MONGO_OK ) { + bson_init_size( out, bson_size( (bson *)&cursor->current ) ); + memcpy( out->data, cursor->current.data, + bson_size( (bson *)&cursor->current ) ); + out->finished = 1; mongo_cursor_destroy( cursor ); return MONGO_OK; } else { @@ -755,56 +1020,49 @@ int mongo_find_one( mongo *conn, const char *ns, bson *query, } } -void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns ) { +MONGO_EXPORT void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns ) { + memset( cursor, 0, sizeof( mongo_cursor ) ); cursor->conn = conn; cursor->ns = ( const char * )bson_malloc( strlen( ns ) + 1 ); strncpy( ( char * )cursor->ns, ns, strlen( ns ) + 1 ); cursor->current.data = NULL; - cursor->reply = NULL; - cursor->flags = 0; - cursor->seen = 0; - cursor->err = 0; - cursor->options = 0; - cursor->query = NULL; - cursor->fields = NULL; - cursor->skip = 0; - cursor->limit = 0; } -void mongo_cursor_set_query( mongo_cursor *cursor, bson *query ) { +MONGO_EXPORT void mongo_cursor_set_query( mongo_cursor *cursor, const bson *query ) { cursor->query = query; } -void mongo_cursor_set_fields( mongo_cursor *cursor, bson *fields ) { +MONGO_EXPORT void mongo_cursor_set_fields( mongo_cursor *cursor, const bson *fields ) { cursor->fields = fields; } -void mongo_cursor_set_skip( mongo_cursor *cursor, int skip ) { +MONGO_EXPORT void mongo_cursor_set_skip( mongo_cursor *cursor, int skip ) { cursor->skip = skip; } -void mongo_cursor_set_limit( mongo_cursor *cursor, int limit ) { +MONGO_EXPORT void mongo_cursor_set_limit( mongo_cursor *cursor, int limit ) { cursor->limit = limit; } -void mongo_cursor_set_options( mongo_cursor *cursor, int options ) { +MONGO_EXPORT void mongo_cursor_set_options( mongo_cursor *cursor, int options ) { cursor->options = options; } -const char *mongo_cursor_data( mongo_cursor *cursor ) { +MONGO_EXPORT const char *mongo_cursor_data( mongo_cursor *cursor ) { return cursor->current.data; } -const bson *mongo_cursor_bson( mongo_cursor *cursor ) { +MONGO_EXPORT const bson *mongo_cursor_bson( mongo_cursor *cursor ) { return (const bson *)&(cursor->current); } -int mongo_cursor_next( mongo_cursor *cursor ) { +MONGO_EXPORT int mongo_cursor_next( mongo_cursor *cursor ) { char *next_object; char *message_end; if( ! ( cursor->flags & MONGO_CURSOR_QUERY_SENT ) ) - mongo_cursor_op_query( cursor ); + if( mongo_cursor_op_query( cursor ) != MONGO_OK ) + return MONGO_ERROR; if( !cursor->reply ) return MONGO_ERROR; @@ -826,7 +1084,7 @@ int mongo_cursor_next( mongo_cursor *cursor ) { /* first */ if ( cursor->current.data == NULL ) { - bson_init_data( &cursor->current, &cursor->reply->objs ); + bson_init_finished_data( &cursor->current, &cursor->reply->objs ); return MONGO_OK; } @@ -843,15 +1101,15 @@ int mongo_cursor_next( mongo_cursor *cursor ) { return MONGO_ERROR; } - bson_init_data( &cursor->current, &cursor->reply->objs ); + bson_init_finished_data( &cursor->current, &cursor->reply->objs ); } else { - bson_init_data( &cursor->current, next_object ); + bson_init_finished_data( &cursor->current, next_object ); } return MONGO_OK; } -int mongo_cursor_destroy( mongo_cursor *cursor ) { +MONGO_EXPORT int mongo_cursor_destroy( mongo_cursor *cursor ) { int result = MONGO_OK; if ( !cursor ) return result; @@ -883,7 +1141,7 @@ int mongo_cursor_destroy( mongo_cursor *cursor ) { /* MongoDB Helper Functions */ -int mongo_create_index( mongo *conn, const char *ns, bson *key, int options, bson *out ) { +MONGO_EXPORT int mongo_create_index( mongo *conn, const char *ns, const bson *key, int options, bson *out ) { bson b; bson_iterator it; char name[255] = {'_'}; @@ -933,10 +1191,10 @@ bson_bool_t mongo_create_simple_index( mongo *conn, const char *ns, const char * return success; } -int64_t mongo_count( mongo *conn, const char *db, const char *ns, bson *query ) { +MONGO_EXPORT double mongo_count( mongo *conn, const char *db, const char *ns, const bson *query ) { bson cmd; bson out = {NULL, 0}; - int64_t count = -1; + double count = -1; bson_init( &cmd ); bson_append_string( &cmd, "count", ns ); @@ -947,7 +1205,7 @@ int64_t mongo_count( mongo *conn, const char *db, const char *ns, bson *query ) if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) { bson_iterator it; if( bson_find( &it, &out, "n" ) ) - count = bson_iterator_long( &it ); + count = bson_iterator_double( &it ); bson_destroy( &cmd ); bson_destroy( &out ); return count; @@ -958,38 +1216,51 @@ int64_t mongo_count( mongo *conn, const char *db, const char *ns, bson *query ) } } -int mongo_run_command( mongo *conn, const char *db, bson *command, +MONGO_EXPORT int mongo_run_command( mongo *conn, const char *db, const bson *command, bson *out ) { + bson response = {NULL, 0}; bson fields; int sl = strlen( db ); char *ns = bson_malloc( sl + 5 + 1 ); /* ".$cmd" + nul */ - int res; + int res, success = 0; strcpy( ns, db ); strcpy( ns+sl, ".$cmd" ); - res = mongo_find_one( conn, ns, command, bson_empty( &fields ), out ); + res = mongo_find_one( conn, ns, command, bson_empty( &fields ), &response ); bson_free( ns ); - return res; + + if( res != MONGO_OK ) + return MONGO_ERROR; + else { + bson_iterator it; + if( bson_find( &it, &response, "ok" ) ) + success = bson_iterator_bool( &it ); + + if( !success ) { + conn->err = MONGO_COMMAND_FAILED; + return MONGO_ERROR; + } else { + if( out ) + *out = response; + return MONGO_OK; + } + } } -int mongo_simple_int_command( mongo *conn, const char *db, +MONGO_EXPORT int mongo_simple_int_command( mongo *conn, const char *db, const char *cmdstr, int arg, bson *realout ) { bson out = {NULL, 0}; bson cmd; - bson_bool_t success = 0; + int result; bson_init( &cmd ); bson_append_int( &cmd, cmdstr, arg ); bson_finish( &cmd ); - if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) { - bson_iterator it; - if( bson_find( &it, &out, "ok" ) ) - success = bson_iterator_bool( &it ); - } + result = mongo_run_command( conn, db, &cmd, &out ); bson_destroy( &cmd ); @@ -998,30 +1269,21 @@ int mongo_simple_int_command( mongo *conn, const char *db, else bson_destroy( &out ); - if( success ) - return MONGO_OK; - else { - conn->err = MONGO_COMMAND_FAILED; - return MONGO_ERROR; - } + return result; } -int mongo_simple_str_command( mongo *conn, const char *db, +MONGO_EXPORT int mongo_simple_str_command( mongo *conn, const char *db, const char *cmdstr, const char *arg, bson *realout ) { bson out = {NULL, 0}; - int success = 0; + int result; bson cmd; bson_init( &cmd ); bson_append_string( &cmd, cmdstr, arg ); bson_finish( &cmd ); - if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) { - bson_iterator it; - if( bson_find( &it, &out, "ok" ) ) - success = bson_iterator_bool( &it ); - } + result = mongo_run_command( conn, db, &cmd, &out ); bson_destroy( &cmd ); @@ -1030,21 +1292,18 @@ int mongo_simple_str_command( mongo *conn, const char *db, else bson_destroy( &out ); - if( success ) - return MONGO_OK; - else - return MONGO_ERROR; + return result; } -int mongo_cmd_drop_db( mongo *conn, const char *db ) { +MONGO_EXPORT int mongo_cmd_drop_db( mongo *conn, const char *db ) { return mongo_simple_int_command( conn, db, "dropDatabase", 1, NULL ); } -int mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out ) { +MONGO_EXPORT int mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out ) { return mongo_simple_str_command( conn, db, "drop", collection, out ); } -void mongo_cmd_reset_error( mongo *conn, const char *db ) { +MONGO_EXPORT void mongo_cmd_reset_error( mongo *conn, const char *db ) { mongo_simple_int_command( conn, db, "reseterror", 1, NULL ); } @@ -1055,23 +1314,13 @@ static int mongo_cmd_get_error_helper( mongo *conn, const char *db, bson_bool_t haserror = 0; /* Reset last error codes. */ - conn->lasterrcode = 0; - bson_free( conn->lasterrstr ); - conn->lasterrstr = NULL; + mongo_clear_errors( conn ); /* If there's an error, store its code and string in the connection object. */ if( mongo_simple_int_command( conn, db, cmdtype, 1, &out ) == MONGO_OK ) { bson_iterator it; haserror = ( bson_find( &it, &out, "err" ) != BSON_NULL ); - if( haserror ) { - conn->lasterrstr = ( char * )bson_malloc( bson_iterator_string_len( &it ) ); - if( conn->lasterrstr ) { - strcpy( conn->lasterrstr, bson_iterator_string( &it ) ); - } - - if( bson_find( &it, &out, "code" ) != BSON_NULL ) - conn->lasterrcode = bson_iterator_int( &it ); - } + if( haserror ) mongo_set_last_error( conn, &it, &out ); } if( realout ) @@ -1085,15 +1334,15 @@ static int mongo_cmd_get_error_helper( mongo *conn, const char *db, return MONGO_OK; } -int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out ) { +MONGO_EXPORT int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out ) { return mongo_cmd_get_error_helper( conn, db, out, "getpreverror" ); } -int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out ) { +MONGO_EXPORT int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out ) { return mongo_cmd_get_error_helper( conn, db, out, "getlasterror" ); } -bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *realout ) { +MONGO_EXPORT bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *realout ) { bson out = {NULL,0}; bson_bool_t ismaster = 0; @@ -1133,7 +1382,7 @@ static void mongo_pass_digest( const char *user, const char *pass, char hex_dige digest2hex( digest, hex_digest ); } -int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass ) { +MONGO_EXPORT int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass ) { bson user_obj; bson pass_obj; char hex_digest[33]; @@ -1164,12 +1413,12 @@ int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const cha return res; } -bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ) { +MONGO_EXPORT bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ) { bson from_db; bson cmd; bson out; const char *nonce; - bson_bool_t success = 0; + int result; mongo_md5_state_t st; mongo_md5_byte_t digest[16]; @@ -1200,18 +1449,11 @@ bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *use bson_finish( &cmd ); bson_destroy( &from_db ); - /*bson_init( &from_db ); */ - if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) { - bson_iterator it; - if( bson_find( &it, &out, "ok" ) ) - success = bson_iterator_bool( &it ); - } + + result = mongo_run_command( conn, db, &cmd, &out ); bson_destroy( &from_db ); bson_destroy( &cmd ); - if( success ) - return MONGO_OK; - else - return MONGO_ERROR; + return result; } diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.h index 6f86174101..dd4c4b4f40 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.h +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.h @@ -3,7 +3,7 @@ * @brief Main MongoDB Declarations */ -/* Copyright 2009-2011 10gen Inc. +/* Copyright 2009-2012 10gen Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,22 +18,26 @@ * limitations under the License. */ -#ifndef _MONGO_H_ -#define _MONGO_H_ +#ifndef MONGO_H_ +#define MONGO_H_ #include "bson.h" MONGO_EXTERN_C_START #define MONGO_MAJOR 0 -#define MONGO_MINOR 4 -#define MONGO_PATCH 0 +#define MONGO_MINOR 5 +#define MONGO_PATCH 2 #define MONGO_OK 0 #define MONGO_ERROR -1 #define MONGO_DEFAULT_PORT 27017 +#define MONGO_DEFAULT_MAX_BSON_SIZE 4 * 1024 * 1024 + +#define MONGO_ERR_LEN 128 + typedef enum mongo_error_t { MONGO_CONN_SUCCESS = 0, /**< Connection success! */ MONGO_CONN_NO_SOCKET, /**< Could not create a socket. */ @@ -43,15 +47,25 @@ typedef enum mongo_error_t { MONGO_CONN_BAD_SET_NAME, /**< Given rs name doesn't match this replica set. */ MONGO_CONN_NO_PRIMARY, /**< Can't find primary in replica set. Connection closed. */ - MONGO_IO_ERROR, /**< An error occurred while reading or writing on socket. */ + MONGO_IO_ERROR, /**< An error occurred while reading or writing on the socket. */ + MONGO_SOCKET_ERROR, /**< Other socket error. */ MONGO_READ_SIZE_ERROR, /**< The response is not the expected length. */ MONGO_COMMAND_FAILED, /**< The command returned with 'ok' value of 0. */ + MONGO_NS_INVALID, /**< The name for the ns (database or collection) is invalid. */ + MONGO_BSON_INVALID, /**< BSON not valid for the specified op. */ + MONGO_BSON_NOT_FINISHED, /**< BSON object has not been finished. */ + MONGO_BSON_TOO_LARGE /**< BSON object exceeds max BSON size. */ +} mongo_error_t; + +typedef enum mongo_cursor_error_t { MONGO_CURSOR_EXHAUSTED, /**< The cursor has no more results. */ MONGO_CURSOR_INVALID, /**< The cursor has timed out or is not recognized. */ MONGO_CURSOR_PENDING, /**< Tailable cursor still alive but no data. */ - MONGO_BSON_INVALID, /**< BSON not valid for the specified op. */ - MONGO_BSON_NOT_FINISHED /**< BSON object has not been finished. */ -} mongo_error_t; + MONGO_CURSOR_QUERY_FAIL, /**< The server returned an '$err' object, indicating query failure. + See conn->lasterrcode and conn->lasterrstr for details. */ + MONGO_CURSOR_BSON_ERROR /**< Something is wrong with the BSON provided. See conn->err + for details. */ +} mongo_cursor_error_t; enum mongo_cursor_flags { MONGO_CURSOR_MUST_FREE = 1, /**< mongo_cursor_destroy should free cursor. */ @@ -137,12 +151,14 @@ typedef struct mongo { int flags; /**< Flags on this connection object. */ int conn_timeout_ms; /**< Connection timeout in milliseconds. */ int op_timeout_ms; /**< Read and write timeout in milliseconds. */ + int max_bson_size; /**< Largest BSON object allowed on this connection. */ bson_bool_t connected; /**< Connection status. */ - mongo_error_t err; /**< Most recent driver error code. */ - char *errstr; /**< String version of most recent driver error code. */ - int lasterrcode; /**< getlasterror given by the server on calls. */ - char *lasterrstr; /**< getlasterror string generated by server. */ + mongo_error_t err; /**< Most recent driver error code. */ + int errcode; /**< Most recent errno or WSAGetLastError(). */ + char errstr[MONGO_ERR_LEN]; /**< String version of error. */ + int lasterrcode; /**< getlasterror code from the server. */ + char lasterrstr[MONGO_ERR_LEN]; /**< getlasterror string from the server. */ } mongo; typedef struct { @@ -152,9 +168,9 @@ typedef struct { int flags; /**< Flags used internally by this drivers. */ int seen; /**< Number returned so far. */ bson current; /**< This cursor's current bson object. */ - mongo_error_t err; /**< Errors on this cursor. */ - bson *query; /**< Bitfield containing cursor options. */ - bson *fields; /**< Bitfield containing cursor options. */ + mongo_cursor_error_t err; /**< Errors on this cursor. */ + const bson *query; /**< Bitfield containing cursor options. */ + const bson *fields;/**< Bitfield containing cursor options. */ int options; /**< Bitfield containing cursor options. */ int limit; /**< Bitfield containing cursor options. */ int skip; /**< Bitfield containing cursor options. */ @@ -162,9 +178,44 @@ typedef struct { /* Connection API */ -/** Initialize a new mongo connection object. If not created - * with mongo_new, you must initialize each mongo - * object using this function. +MONGO_EXPORT mongo* mongo_create(); +MONGO_EXPORT void mongo_dispose(mongo* conn); +MONGO_EXPORT int mongo_get_err(mongo* conn); +MONGO_EXPORT int mongo_is_connected(mongo* conn); +MONGO_EXPORT int mongo_get_op_timeout(mongo* conn); +MONGO_EXPORT const char* mongo_get_primary(mongo* conn); +MONGO_EXPORT int mongo_get_socket(mongo* conn) ; +MONGO_EXPORT int mongo_get_host_count(mongo* conn); +MONGO_EXPORT const char* mongo_get_host(mongo* conn, int i); +MONGO_EXPORT mongo_cursor* mongo_cursor_create(); +MONGO_EXPORT void mongo_cursor_dispose(mongo_cursor* cursor); +MONGO_EXPORT int mongo_get_server_err(mongo* conn); +MONGO_EXPORT const char* mongo_get_server_err_string(mongo* conn); + +/** + * Set an error this mongo connection object. Mostly for internal use. + * + * @param conn a mongo connection object. + * @param err a driver error code of mongo_error_t. + * @param errstr a string version of the error. + * @param errorcode Currently errno or WSAGetLastError(). + */ +MONGO_EXPORT void __mongo_set_error( mongo *conn, mongo_error_t err, + const char *errstr, int errorcode ); +/** + * Clear all errors stored on this mongo connection object. + * + * @param conn a mongo connection object. + */ +MONGO_EXPORT void mongo_clear_errors( mongo *conn ); + +/** Initialize sockets for Windows. + */ +MONGO_EXPORT void mongo_init_sockets(); + +/** + * Initialize a new mongo connection object. You must initialize each mongo + * object using this function. * * @note When finished, you must pass this object to * mongo_destroy( ). @@ -172,7 +223,7 @@ typedef struct { * @param conn a mongo connection object allocated on the stack * or heap. */ -void mongo_init( mongo *conn ); +MONGO_EXPORT void mongo_init( mongo *conn ); /** * Connect to a single MongoDB server. @@ -182,9 +233,9 @@ void mongo_init( mongo *conn ); * @param port the port to connect to. * * @return MONGO_OK or MONGO_ERROR on failure. On failure, a constant of type - * mongo_conn_return_t will be set on the conn->err field. + * mongo_error_t will be set on the conn->err field. */ -int mongo_connect( mongo *conn , const char *host, int port ); +MONGO_EXPORT int mongo_connect( mongo *conn , const char *host, int port ); /** * Set up this connection object for connecting to a replica set. @@ -193,7 +244,7 @@ int mongo_connect( mongo *conn , const char *host, int port ); * @param conn a mongo object. * @param name the name of the replica set to connect to. * */ -void mongo_replset_init( mongo *conn, const char *name ); +MONGO_EXPORT void mongo_replset_init( mongo *conn, const char *name ); /** * Add a seed node to the replica set connection object. @@ -204,7 +255,7 @@ void mongo_replset_init( mongo *conn, const char *name ); * @param host a numerical network address or a network hostname. * @param port the port to connect to. */ -void mongo_replset_add_seed( mongo *conn, const char *host, int port ); +MONGO_EXPORT void mongo_replset_add_seed( mongo *conn, const char *host, int port ); /** * Utility function for converting a host-port string to a mongo_host_port. @@ -215,6 +266,17 @@ void mongo_replset_add_seed( mongo *conn, const char *host, int port ); */ void mongo_parse_host( const char *host_string, mongo_host_port *host_port ); +/** + * Utility function for validation database and collection names. + * + * @param conn a mongo object. + * + * @return MONGO_OK or MONGO_ERROR on failure. On failure, a constant of type + * mongo_conn_return_t will be set on the conn->err field. + * + */ +MONGO_EXPORT int mongo_validate_ns( mongo *conn, const char *ns ); + /** * Connect to a replica set. * @@ -226,7 +288,7 @@ void mongo_parse_host( const char *host_string, mongo_host_port *host_port ); * @return MONGO_OK or MONGO_ERROR on failure. On failure, a constant of type * mongo_conn_return_t will be set on the conn->err field. */ -int mongo_replset_connect( mongo *conn ); +MONGO_EXPORT int mongo_replset_connect( mongo *conn ); /** Set a timeout for operations on this connection. This * is a platform-specific feature, and only work on *nix @@ -238,7 +300,7 @@ int mongo_replset_connect( mongo *conn ); * @return MONGO_OK. On error, return MONGO_ERROR and * set the conn->err field. */ -int mongo_set_op_timeout( mongo *conn, int millis ); +MONGO_EXPORT int mongo_set_op_timeout( mongo *conn, int millis ); /** * Ensure that this connection is healthy by performing @@ -248,7 +310,7 @@ int mongo_set_op_timeout( mongo *conn, int millis ); * * @return MONGO_OK if connected; otherwise, MONGO_ERROR. */ -int mongo_check_connection( mongo *conn ); +MONGO_EXPORT int mongo_check_connection( mongo *conn ); /** * Try reconnecting to the server using the existing connection settings. @@ -261,7 +323,7 @@ int mongo_check_connection( mongo *conn ); * @return MONGO_OK or MONGO_ERROR and * set the conn->err field. */ -int mongo_reconnect( mongo *conn ); +MONGO_EXPORT int mongo_reconnect( mongo *conn ); /** * Close the current connection to the server. After calling @@ -270,7 +332,7 @@ int mongo_reconnect( mongo *conn ); * * @param conn a mongo object. */ -void mongo_disconnect( mongo *conn ); +MONGO_EXPORT void mongo_disconnect( mongo *conn ); /** * Close any existing connection to the server and free all allocated @@ -280,7 +342,7 @@ void mongo_disconnect( mongo *conn ); * * @param conn a mongo object. */ -void mongo_destroy( mongo *conn ); +MONGO_EXPORT void mongo_destroy( mongo *conn ); /** * Insert a BSON document into a MongoDB server. This function @@ -295,7 +357,7 @@ void mongo_destroy( mongo *conn ); * field is MONGO_BSON_INVALID, check the err field * on the bson struct for the reason. */ -int mongo_insert( mongo *conn, const char *ns, bson *data ); +MONGO_EXPORT int mongo_insert( mongo *conn, const char *ns, const bson *data ); /** * Insert a batch of BSON documents into a MongoDB server. This function @@ -309,8 +371,8 @@ int mongo_insert( mongo *conn, const char *ns, bson *data ); * @return MONGO_OK or MONGO_ERROR. * */ -int mongo_insert_batch( mongo *conn , const char *ns , - bson **data , int num ); +MONGO_EXPORT int mongo_insert_batch( mongo *conn , const char *ns , + const bson **data , int num ); /** * Update a document in a MongoDB server. @@ -324,7 +386,7 @@ int mongo_insert_batch( mongo *conn , const char *ns , * @return MONGO_OK or MONGO_ERROR with error stored in conn object. * */ -int mongo_update( mongo *conn, const char *ns, const bson *cond, +MONGO_EXPORT int mongo_update( mongo *conn, const char *ns, const bson *cond, const bson *op, int flags ); /** @@ -336,7 +398,7 @@ int mongo_update( mongo *conn, const char *ns, const bson *cond, * * @return MONGO_OK or MONGO_ERROR with error stored in conn object. */ -int mongo_remove( mongo *conn, const char *ns, const bson *cond ); +MONGO_EXPORT int mongo_remove( mongo *conn, const char *ns, const bson *cond ); /** * Find documents in a MongoDB server. @@ -353,8 +415,8 @@ int mongo_remove( mongo *conn, const char *ns, const bson *cond ); * an error has occurred. For finer-grained error checking, * use the cursor builder API instead. */ -mongo_cursor *mongo_find( mongo *conn, const char *ns, bson *query, - bson *fields, int limit, int skip, int options ); +MONGO_EXPORT mongo_cursor *mongo_find( mongo *conn, const char *ns, const bson *query, + const bson *fields, int limit, int skip, int options ); /** * Initalize a new cursor object. @@ -363,7 +425,7 @@ mongo_cursor *mongo_find( mongo *conn, const char *ns, bson *query, * @param ns the namespace, represented as the the database * name and collection name separated by a dot. e.g., "test.users" */ -void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns ); +MONGO_EXPORT void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns ); /** * Set the bson object specifying this cursor's query spec. If @@ -376,7 +438,7 @@ void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns ); * $query, $orderby, $hint, and/or $explain. See * http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol for details. */ -void mongo_cursor_set_query( mongo_cursor *cursor, bson *query ); +MONGO_EXPORT void mongo_cursor_set_query( mongo_cursor *cursor, const bson *query ); /** * Set the fields to return for this cursor. If you want to return @@ -386,7 +448,7 @@ void mongo_cursor_set_query( mongo_cursor *cursor, bson *query ); * @param fields a bson object representing the fields to return. * See http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields. */ -void mongo_cursor_set_fields( mongo_cursor *cursor, bson *fields ); +MONGO_EXPORT void mongo_cursor_set_fields( mongo_cursor *cursor, const bson *fields ); /** * Set the number of documents to skip. @@ -394,7 +456,7 @@ void mongo_cursor_set_fields( mongo_cursor *cursor, bson *fields ); * @param cursor * @param skip */ -void mongo_cursor_set_skip( mongo_cursor *cursor, int skip ); +MONGO_EXPORT void mongo_cursor_set_skip( mongo_cursor *cursor, int skip ); /** * Set the number of documents to return. @@ -402,7 +464,7 @@ void mongo_cursor_set_skip( mongo_cursor *cursor, int skip ); * @param cursor * @param limit */ -void mongo_cursor_set_limit( mongo_cursor *cursor, int limit ); +MONGO_EXPORT void mongo_cursor_set_limit( mongo_cursor *cursor, int limit ); /** * Set any of the available query options (e.g., MONGO_TAILABLE). @@ -411,7 +473,7 @@ void mongo_cursor_set_limit( mongo_cursor *cursor, int limit ); * @param options a bitfield storing query options. See * mongo_cursor_bitfield_t for available constants. */ -void mongo_cursor_set_options( mongo_cursor *cursor, int options ); +MONGO_EXPORT void mongo_cursor_set_options( mongo_cursor *cursor, int options ); /** * Return the current BSON object data as a const char*. This is useful @@ -419,7 +481,7 @@ void mongo_cursor_set_options( mongo_cursor *cursor, int options ); * * @param cursor */ -const char *mongo_cursor_data( mongo_cursor *cursor ); +MONGO_EXPORT const char *mongo_cursor_data( mongo_cursor *cursor ); /** * Return the current BSON object data as a const char*. This is useful @@ -427,7 +489,7 @@ const char *mongo_cursor_data( mongo_cursor *cursor ); * * @param cursor */ -const bson *mongo_cursor_bson( mongo_cursor *cursor ); +MONGO_EXPORT const bson *mongo_cursor_bson( mongo_cursor *cursor ); /** * Iterate the cursor, returning the next item. When successful, @@ -438,7 +500,7 @@ const bson *mongo_cursor_bson( mongo_cursor *cursor ); * @return MONGO_OK. On error, returns MONGO_ERROR and sets * cursor->err with a value of mongo_error_t. */ -int mongo_cursor_next( mongo_cursor *cursor ); +MONGO_EXPORT int mongo_cursor_next( mongo_cursor *cursor ); /** * Destroy a cursor object. When finished with a cursor, you @@ -449,7 +511,7 @@ int mongo_cursor_next( mongo_cursor *cursor ); * @return MONGO_OK or an error code. On error, check cursor->conn->err * for errors. */ -int mongo_cursor_destroy( mongo_cursor *cursor ); +MONGO_EXPORT int mongo_cursor_destroy( mongo_cursor *cursor ); /** * Find a single document in a MongoDB server. @@ -462,8 +524,8 @@ int mongo_cursor_destroy( mongo_cursor *cursor ); * */ /* out can be NULL if you don't care about results. useful for commands */ -bson_bool_t mongo_find_one( mongo *conn, const char *ns, bson *query, - bson *fields, bson *out ); +MONGO_EXPORT int mongo_find_one( mongo *conn, const char *ns, const bson *query, + const bson *fields, bson *out ); /* MongoDB Helper Functions */ @@ -478,8 +540,8 @@ bson_bool_t mongo_find_one( mongo *conn, const char *ns, bson *query, * @return the number of matching documents. If the command fails, * MONGO_ERROR is returned. */ -int64_t mongo_count( mongo *conn, const char *db, const char *coll, - bson *query ); +MONGO_EXPORT double mongo_count( mongo *conn, const char *db, const char *coll, + const bson *query ); /** * Create a compouned index. @@ -494,7 +556,7 @@ int64_t mongo_count( mongo *conn, const char *db, const char *coll, * * @return MONGO_OK if index is created successfully; otherwise, MONGO_ERROR. */ -int mongo_create_index( mongo *conn, const char *ns, bson *key, int options, bson *out ); +MONGO_EXPORT int mongo_create_index( mongo *conn, const char *ns, const bson *key, int options, bson *out ); /** * Create an index with a single key. @@ -521,9 +583,9 @@ bson_bool_t mongo_create_simple_index( mongo *conn, const char *ns, const char * * @param command the BSON command to run. * @param out the BSON result of the command. * - * @return true if the command ran without error. + * @return MONGO_OK if the command ran without error. */ -bson_bool_t mongo_run_command( mongo *conn, const char *db, bson *command, bson *out ); +MONGO_EXPORT int mongo_run_command( mongo *conn, const char *db, const bson *command, bson *out ); /** * Run a command that accepts a simple string key and integer value. @@ -537,7 +599,7 @@ bson_bool_t mongo_run_command( mongo *conn, const char *db, bson *command, bson * @return MONGO_OK or an error code. * */ -int mongo_simple_int_command( mongo *conn, const char *db, +MONGO_EXPORT int mongo_simple_int_command( mongo *conn, const char *db, const char *cmd, int arg, bson *out ); /** @@ -552,7 +614,7 @@ int mongo_simple_int_command( mongo *conn, const char *db, * @return true if the command ran without error. * */ -bson_bool_t mongo_simple_str_command( mongo *conn, const char *db, const char *cmd, const char *arg, bson *out ); +MONGO_EXPORT int mongo_simple_str_command( mongo *conn, const char *db, const char *cmd, const char *arg, bson *out ); /** * Drop a database. @@ -562,7 +624,7 @@ bson_bool_t mongo_simple_str_command( mongo *conn, const char *db, const char *c * * @return MONGO_OK or an error code. */ -int mongo_cmd_drop_db( mongo *conn, const char *db ); +MONGO_EXPORT int mongo_cmd_drop_db( mongo *conn, const char *db ); /** * Drop a collection. @@ -574,7 +636,7 @@ int mongo_cmd_drop_db( mongo *conn, const char *db ); * * @return true if the collection drop was successful. */ -bson_bool_t mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out ); +MONGO_EXPORT int mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out ); /** * Add a database user. @@ -586,7 +648,7 @@ bson_bool_t mongo_cmd_drop_collection( mongo *conn, const char *db, const char * * * @return MONGO_OK or MONGO_ERROR. */ -int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass ); +MONGO_EXPORT int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass ); /** * Authenticate a user. @@ -598,7 +660,7 @@ int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const cha * * @return MONGO_OK on sucess and MONGO_ERROR on failure. */ -int mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ); +MONGO_EXPORT int mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ); /** * Check if the current server is a master. @@ -609,7 +671,7 @@ int mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const * @return true if the server is a master. */ /* return value is master status */ -bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *out ); +MONGO_EXPORT bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *out ); /** * Get the error for the last command with the current connection. @@ -621,7 +683,7 @@ bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *out ); * @return MONGO_OK if no error and MONGO_ERROR on error. On error, check the values * of conn->lasterrcode and conn->lasterrstr for the error status. */ -int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out ); +MONGO_EXPORT int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out ); /** * Get the most recent error with the current connection. @@ -633,7 +695,7 @@ int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out ); * @return MONGO_OK if no error and MONGO_ERROR on error. On error, check the values * of conn->lasterrcode and conn->lasterrstr for the error status. */ -int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out ); +MONGO_EXPORT int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out ); /** * Reset the error state for the connection. @@ -641,7 +703,8 @@ int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out ); * @param conn a mongo object. * @param db the name of the database. */ -void mongo_cmd_reset_error( mongo *conn, const char *db ); +MONGO_EXPORT void mongo_cmd_reset_error( mongo *conn, const char *db ); + MONGO_EXTERN_C_END diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.c deleted file mode 100644 index 5c8ad9ba5e..0000000000 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.c +++ /dev/null @@ -1,98 +0,0 @@ -/* net.c */ - -/* Copyright 2009-2011 10gen Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Implementation for generic version of net.h */ -#include "net.h" -#include <string.h> - -int mongo_write_socket( mongo *conn, const void *buf, int len ) { - const char *cbuf = buf; - while ( len ) { - int sent = send( conn->sock, cbuf, len, 0 ); - if ( sent == -1 ) { - conn->err = MONGO_IO_ERROR; - return MONGO_ERROR; - } - cbuf += sent; - len -= sent; - } - - return MONGO_OK; -} - -int mongo_read_socket( mongo *conn, void *buf, int len ) { - char *cbuf = buf; - while ( len ) { - int sent = recv( conn->sock, cbuf, len, 0 ); - if ( sent == 0 || sent == -1 ) { - conn->err = MONGO_IO_ERROR; - return MONGO_ERROR; - } - cbuf += sent; - len -= sent; - } - - return MONGO_OK; -} - -/* This is a no-op in the generic implementation. */ -int mongo_set_socket_op_timeout( mongo *conn, int millis ) { - return MONGO_OK; -} - -static int mongo_create_socket( mongo *conn ) { - int fd; - - if( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) { - conn->err = MONGO_CONN_NO_SOCKET; - return MONGO_ERROR; - } - conn->sock = fd; - - return MONGO_OK; -} - -int mongo_socket_connect( mongo *conn, const char *host, int port ) { - struct sockaddr_in sa; - socklen_t addressSize; - int flag = 1; - - if( mongo_create_socket( conn ) != MONGO_OK ) - return MONGO_ERROR; - - memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) ); - sa.sin_family = AF_INET; - sa.sin_port = htons( port ); - sa.sin_addr.s_addr = inet_addr( host ); - addressSize = sizeof( sa ); - - if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) { - mongo_close_socket( conn->sock ); - conn->connected = 0; - conn->sock = 0; - conn->err = MONGO_CONN_FAIL; - return MONGO_ERROR; - } - - setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) ); - if( conn->op_timeout_ms > 0 ) - mongo_set_socket_op_timeout( conn, conn->op_timeout_ms ); - - conn->connected = 1; - - return MONGO_OK; -} diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.h deleted file mode 100644 index 49190877c8..0000000000 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.h +++ /dev/null @@ -1,57 +0,0 @@ -/** @file net.h */ - -/* Copyright 2009-2011 10gen Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Header for generic net.h */ -#ifndef _MONGO_NET_H_ -#define _MONGO_NET_H_ - -#include "mongo.h" - -#ifdef _WIN32 -#include <windows.h> -#include <winsock.h> -#define mongo_close_socket(sock) ( closesocket(sock) ) -typedef int socklen_t; -#else -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <fcntl.h> -#define mongo_close_socket(sock) ( close(sock) ) -#endif - -#ifndef _WIN32 -#include <unistd.h> -#endif - -#if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || _POSIX_C_SOURCE >= 1 -#define _MONGO_USE_GETADDRINFO -#endif - -MONGO_EXTERN_C_START - -/* This is a no-op in the generic implementation. */ -int mongo_set_socket_op_timeout( mongo *conn, int millis ); -int mongo_read_socket( mongo *conn, void *buf, int len ); -int mongo_write_socket( mongo *conn, const void *buf, int len ); -int mongo_socket_connect( mongo *conn, const char *host, int port ); - -MONGO_EXTERN_C_END -#endif diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/numbers.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/numbers.c index a63e3d73f9..b3032d5ee3 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/numbers.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/numbers.c @@ -1,4 +1,4 @@ -/* Copyright 2009-2011 10gen Inc. +/* Copyright 2009-2012 10gen Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform.h deleted file mode 100644 index 4a96af77e3..0000000000 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform.h +++ /dev/null @@ -1,94 +0,0 @@ -/** @file platform.h */ - -/** Copyright 2009-2011 10gen Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -/* all platform-specific ifdefs should go here */ - -#ifndef _PLATFORM_HACKS_H_ -#define _PLATFORM_HACKS_H_ - -#ifdef __GNUC__ -#define MONGO_INLINE static __inline__ -#else -#define MONGO_INLINE static -#endif - -#ifdef __cplusplus -#define MONGO_EXTERN_C_START extern "C" { -#define MONGO_EXTERN_C_END } -#else -#define MONGO_EXTERN_C_START -#define MONGO_EXTERN_C_END -#endif - - -#if defined(MONGO_HAVE_STDINT) || __STDC_VERSION__ >= 199901L -#include <stdint.h> -#elif defined(MONGO_HAVE_UNISTD) -#include <unistd.h> -#elif defined(MONGO_USE__INT64) -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#elif defined(MONGO_USE_LONG_LONG_INT) -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#else -#error must have a 64bit int type -#endif - -/* big endian is only used for OID generation. little is used everywhere else */ -#ifdef MONGO_BIG_ENDIAN -#define bson_little_endian64(out, in) ( bson_swap_endian64(out, in) ) -#define bson_little_endian32(out, in) ( bson_swap_endian32(out, in) ) -#define bson_big_endian64(out, in) ( memcpy(out, in, 8) ) -#define bson_big_endian32(out, in) ( memcpy(out, in, 4) ) -#else -#define bson_little_endian64(out, in) ( memcpy(out, in, 8) ) -#define bson_little_endian32(out, in) ( memcpy(out, in, 4) ) -#define bson_big_endian64(out, in) ( bson_swap_endian64(out, in) ) -#define bson_big_endian32(out, in) ( bson_swap_endian32(out, in) ) -#endif - -MONGO_EXTERN_C_START - -MONGO_INLINE void bson_swap_endian64( void *outp, const void *inp ) { - const char *in = ( const char * )inp; - char *out = ( char * )outp; - - out[0] = in[7]; - out[1] = in[6]; - out[2] = in[5]; - out[3] = in[4]; - out[4] = in[3]; - out[5] = in[2]; - out[6] = in[1]; - out[7] = in[0]; - -} -MONGO_INLINE void bson_swap_endian32( void *outp, const void *inp ) { - const char *in = ( const char * )inp; - char *out = ( char * )outp; - - out[0] = in[3]; - out[1] = in[2]; - out[2] = in[1]; - out[3] = in[0]; -} - -MONGO_EXTERN_C_END - -#endif diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.c deleted file mode 100644 index b2f7c22898..0000000000 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.c +++ /dev/null @@ -1,183 +0,0 @@ -/* net.c */ - -/* Copyright 2009-2011 10gen Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Implementation for Linux version of net.h */ -#include "net.h" -#include <string.h> - -int mongo_write_socket( mongo *conn, const void *buf, int len ) { - const char *cbuf = buf; - while ( len ) { - int sent = send( conn->sock, cbuf, len, 0 ); - if ( sent == -1 ) { - conn->err = MONGO_IO_ERROR; - return MONGO_ERROR; - } - cbuf += sent; - len -= sent; - } - - return MONGO_OK; -} - -int mongo_read_socket( mongo *conn, void *buf, int len ) { - char *cbuf = buf; - while ( len ) { - int sent = recv( conn->sock, cbuf, len, 0 ); - if ( sent == 0 || sent == -1 ) { - conn->err = MONGO_IO_ERROR; - return MONGO_ERROR; - } - cbuf += sent; - len -= sent; - } - - return MONGO_OK; -} - -static int mongo_create_socket( mongo *conn ) { - int fd; - - if( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) { - conn->err = MONGO_CONN_NO_SOCKET; - return MONGO_ERROR; - } - conn->sock = fd; - - return MONGO_OK; -} - -static int mongo_set_blocking_status( mongo *conn ) { - int flags; - int blocking; - - blocking = ( conn->conn_timeout_ms == 0 ); - if( blocking ) - return MONGO_OK; - else { - if( ( flags = fcntl( conn->sock, F_GETFL ) ) == -1 ) { - conn->err = MONGO_IO_ERROR; - mongo_close_socket( conn->sock ); - return MONGO_ERROR; - } - - flags |= O_NONBLOCK; - - if( ( flags = fcntl( conn->sock, F_SETFL, flags ) ) == -1 ) { - conn->err = MONGO_IO_ERROR; - mongo_close_socket( conn->sock ); - return MONGO_ERROR; - } - } - - return MONGO_OK; -} - -int mongo_set_socket_op_timeout( mongo *conn, int millis ) { - struct timeval tv; - tv.tv_sec = millis / 1000; - tv.tv_usec = ( millis % 1000 ) * 1000; - - if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) ) == -1 ) { - conn->err = MONGO_IO_ERROR; - return MONGO_ERROR; - } - - if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof( tv ) ) == -1 ) { - conn->err = MONGO_IO_ERROR; - return MONGO_ERROR; - } - - return MONGO_OK; -} - -#ifdef _MONGO_USE_GETADDRINFO -int mongo_socket_connect( mongo *conn, const char *host, int port ) { - - struct addrinfo *addrs = NULL; - struct addrinfo hints; - int flag = 1; - char port_str[12]; - int ret; - - conn->sock = 0; - conn->connected = 0; - - memset( &hints, 0, sizeof( hints ) ); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - - sprintf( port_str, "%d", port ); - - if( mongo_create_socket( conn ) != MONGO_OK ) - return MONGO_ERROR; - - if( getaddrinfo( host, port_str, &hints, &addrs ) != 0 ) { - bson_errprintf( "getaddrinfo failed: %s", gai_strerror( ret ) ); - conn->err = MONGO_CONN_ADDR_FAIL; - return MONGO_ERROR; - } - - if ( connect( conn->sock, addrs->ai_addr, addrs->ai_addrlen ) == -1 ) { - mongo_close_socket( conn->sock ); - freeaddrinfo( addrs ); - conn->err = MONGO_CONN_FAIL; - return MONGO_ERROR; - } - - setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * )&flag, sizeof( flag ) ); - if( conn->op_timeout_ms > 0 ) - mongo_set_socket_op_timeout( conn, conn->op_timeout_ms ); - - conn->connected = 1; - freeaddrinfo( addrs ); - - return MONGO_OK; -} -#else -int mongo_socket_connect( mongo *conn, const char *host, int port ) { - struct sockaddr_in sa; - socklen_t addressSize; - int flag = 1; - - if( mongo_create_socket( conn ) != MONGO_OK ) - return MONGO_ERROR; - - memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) ); - sa.sin_family = AF_INET; - sa.sin_port = htons( port ); - sa.sin_addr.s_addr = inet_addr( host ); - addressSize = sizeof( sa ); - - if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) { - mongo_close_socket( conn->sock ); - conn->connected = 0; - conn->sock = 0; - conn->err = MONGO_CONN_FAIL; - return MONGO_ERROR; - } - - setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) ); - - if( conn->op_timeout_ms > 0 ) - mongo_set_socket_op_timeout( conn, conn->op_timeout_ms ); - - conn->connected = 1; - - return MONGO_OK; -} -#endif diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.h deleted file mode 100644 index 054247c1e8..0000000000 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file net.h - * @brief Networking. - */ - -/* Copyright 2009-2011 10gen Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Header for Linux net.h */ -#ifndef _MONGO_NET_H_ -#define _MONGO_NET_H_ - -#include "mongo.h" - -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#define mongo_close_socket(sock) ( close(sock) ) - -#if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || _POSIX_C_SOURCE >= 1 -#define _MONGO_USE_GETADDRINFO -#endif - -MONGO_EXTERN_C_START - -int mongo_set_socket_op_timeout( mongo *conn, int millis ); -int mongo_read_socket( mongo *conn, void *buf, int len ); -int mongo_write_socket( mongo *conn, const void *buf, int len ); -int mongo_socket_connect( mongo *conn, const char *host, int port ); - -MONGO_EXTERN_C_END -#endif