├── mongo-c-driver-v0.6 ├── docs │ ├── buildscripts │ │ ├── __init__.py │ │ └── docs.py │ ├── source │ │ └── sphinx │ │ │ ├── source │ │ │ ├── index.rst │ │ │ ├── errors.rst │ │ │ ├── write_concern.rst │ │ │ ├── connections.rst │ │ │ ├── building.rst │ │ │ ├── bson.rst │ │ │ └── conf.py │ │ │ ├── make.bat │ │ │ └── Makefile │ └── examples │ │ └── example.c ├── .astylerc ├── .gitignore ├── test │ ├── sizes_test.c │ ├── oid_test.c │ ├── auth_test.c │ ├── endian_swap_test.c │ ├── platform │ │ └── linux │ │ │ └── timeouts.c │ ├── resize_test.c │ ├── commands_test.c │ ├── bson_subobject_test.c │ ├── helpers_test.c │ ├── cpptest.cpp │ ├── test.h │ ├── count_delete_test.c │ ├── examples_test.c │ ├── functions_test.c │ ├── env_posix_test.c │ ├── update_test.c │ ├── env_win32_test.c │ ├── replica_set_test.c │ ├── validate_test.c │ ├── simple_test.c │ ├── cursors_test.c │ ├── json_test.c │ ├── gridfs_test.c │ ├── errors_test.c │ ├── bson_test.c │ └── write_concern_test.c ├── runtests.sh ├── check_int64.sh ├── src │ ├── env.h │ ├── encoding.h │ ├── md5.h │ ├── env_standard.c │ ├── env_posix.c │ ├── env_win32.c │ ├── encoding.c │ └── numbers.c ├── README.md ├── Makefile └── HISTORY.md ├── mongo_fdw.control ├── .gitignore ├── mongo_query.h ├── mongo_fdw--1.0.sql ├── Makefile ├── CONTRIBUTING.md ├── mongo_fdw.h ├── README.md └── LICENSE /mongo-c-driver-v0.6/docs/buildscripts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/.astylerc: -------------------------------------------------------------------------------- 1 | --style=java 2 | --pad-paren-in 3 | --pad-paren-in 4 | --align-pointer=name 5 | -------------------------------------------------------------------------------- /mongo_fdw.control: -------------------------------------------------------------------------------- 1 | # mongo_fdw extension 2 | # 3 | # Copyright (c) 2012-2014 Citus Data, Inc. 4 | # 5 | comment = 'foreign data wrapper for MongoDB access' 6 | default_version = '1.0' 7 | module_pathname = '$libdir/mongo_fdw' 8 | relocatable = true 9 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *~ 3 | *.o 4 | *.os 5 | *.obj 6 | *.a 7 | *.lib 8 | *.so 9 | *.dylib 10 | .scon* 11 | *.pyc 12 | *.swp 13 | 14 | .DS_Store 15 | 16 | test_* 17 | benchmark 18 | benchmark.exe 19 | 20 | tags 21 | 22 | config.log 23 | 24 | docs/html 25 | docs/source/sphinx/build 26 | docs/source/doxygen 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ===== 2 | # = C = 3 | # ===== 4 | 5 | # Object files 6 | *.o 7 | *.ko 8 | *.obj 9 | *.elf 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | 15 | # Shared objects (inc. Windows DLLs) 16 | *.dll 17 | *.so 18 | *.so.* 19 | *.dylib 20 | 21 | # Executables 22 | *.exe 23 | *.out 24 | *.app 25 | *.i*86 26 | *.x86_64 27 | *.hex 28 | -------------------------------------------------------------------------------- /mongo_query.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * mongo_query.h 4 | * 5 | * Type and function declarations for constructing queries to send to MongoDB. 6 | * 7 | * Copyright (c) 2012-2014 Citus Data, Inc. 8 | * 9 | *------------------------------------------------------------------------- 10 | */ 11 | 12 | #ifndef MONGO_QUERY_H 13 | #define MONGO_QUERY_H 14 | 15 | 16 | 17 | 18 | #endif /* MONGO_QUERY_H */ 19 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/sizes_test.c: -------------------------------------------------------------------------------- 1 | /* sizes.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include 6 | 7 | int main() { 8 | mongo_reply mr; 9 | 10 | ASSERT( sizeof( int ) == 4 ); 11 | ASSERT( sizeof( int64_t ) == 8 ); 12 | ASSERT( sizeof( double ) == 8 ); 13 | ASSERT( sizeof( bson_oid_t ) == 12 ); 14 | 15 | ASSERT( sizeof( mongo_header ) == 4+4+4+4 ); 16 | ASSERT( sizeof( mongo_reply_fields ) == 4+8+4+4 ); 17 | 18 | /* field offset of obj in mongo_reply */ 19 | ASSERT( ( &mr.objs - ( char * )&mr ) == ( 4+4+4+4 + 4+8+4+4 ) ); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /mongo_fdw--1.0.sql: -------------------------------------------------------------------------------- 1 | /* mongo_fdw/mongo_fdw--1.0.sql */ 2 | 3 | -- Copyright (c) 2012-2014 Citus Data, Inc. 4 | 5 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 6 | \echo Use "CREATE EXTENSION mongo_fdw" to load this file. \quit 7 | 8 | CREATE FUNCTION mongo_fdw_handler() 9 | RETURNS fdw_handler 10 | AS 'MODULE_PATHNAME' 11 | LANGUAGE C STRICT; 12 | 13 | CREATE FUNCTION mongo_fdw_validator(text[], oid) 14 | RETURNS void 15 | AS 'MODULE_PATHNAME' 16 | LANGUAGE C STRICT; 17 | 18 | CREATE FOREIGN DATA WRAPPER mongo_fdw 19 | HANDLER mongo_fdw_handler 20 | VALIDATOR mongo_fdw_validator; 21 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Arguments -v for valgrind 3 | 4 | usage() 5 | { 6 | cat < 6 | #include 7 | #include 8 | #include 9 | 10 | int increment( void ) { 11 | static int i = 1000; 12 | i++; 13 | return i; 14 | } 15 | 16 | int fuzz( void ) { 17 | return 50000; 18 | } 19 | 20 | /* Test custom increment and fuzz functions. */ 21 | int main() { 22 | 23 | bson_oid_t o; 24 | int res; 25 | 26 | bson_set_oid_inc( increment ); 27 | bson_set_oid_fuzz( fuzz ); 28 | 29 | bson_oid_gen( &o ); 30 | bson_big_endian32( &res, &( o.ints[2] ) ); 31 | 32 | ASSERT( o.ints[1] == 50000 ); 33 | ASSERT( res == 1001 ); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/auth_test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "mongo.h" 3 | #include 4 | #include 5 | #include 6 | 7 | static const char *db = "test"; 8 | 9 | int main() { 10 | 11 | mongo conn[1]; 12 | 13 | INIT_SOCKETS_FOR_WINDOWS; 14 | 15 | if ( mongo_connect( conn , TEST_SERVER, 27017 ) ) { 16 | printf( "failed to connect\n" ); 17 | exit( 1 ); 18 | } 19 | 20 | mongo_cmd_drop_db( conn, db ); 21 | 22 | ASSERT( mongo_cmd_authenticate( conn, db, "user", "password" ) == MONGO_ERROR ); 23 | mongo_cmd_add_user( conn, db, "user", "password" ); 24 | ASSERT( mongo_cmd_authenticate( conn, db, "user", "password" ) == MONGO_OK ); 25 | 26 | mongo_cmd_drop_db( conn, db ); 27 | mongo_destroy( conn ); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/check_int64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2009, 2010 10gen Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # $1 is C compiler. $2 is header file 18 | cat <tmp.c && $1 -o header_check.tmp tmp.c 19 | #include <$2> 20 | int main() { int64_t i=0; return 0; } 21 | EOF 22 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/endian_swap_test.c: -------------------------------------------------------------------------------- 1 | /* endian_swap.c */ 2 | 3 | #include "test.h" 4 | #include "bson.h" 5 | #include 6 | 7 | int main() { 8 | int small = 0x00112233; 9 | int64_t big = 0x0011223344556677; 10 | double d = 1.2345; 11 | 12 | int small_swap; 13 | int64_t big_swap; 14 | int64_t d_swap; 15 | 16 | bson_swap_endian32( &small_swap, &small ); 17 | ASSERT( small_swap == 0x33221100 ); 18 | bson_swap_endian32( &small, &small_swap ); 19 | ASSERT( small == 0x00112233 ); 20 | 21 | bson_swap_endian64( &big_swap, &big ); 22 | ASSERT( big_swap == 0x7766554433221100 ); 23 | bson_swap_endian64( &big, &big_swap ); 24 | ASSERT( big == 0x0011223344556677 ); 25 | 26 | bson_swap_endian64( &d_swap, &d ); 27 | bson_swap_endian64( &d, &d_swap ); 28 | ASSERT( d == 1.2345 ); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/platform/linux/timeouts.c: -------------------------------------------------------------------------------- 1 | /* timeouts.c */ 2 | 3 | #include "../../test.h" 4 | #include "mongo.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | 12 | mongo conn[1]; 13 | bson b; 14 | int res; 15 | 16 | if( mongo_connect( conn, TEST_SERVER, 27017 ) != MONGO_OK ) { 17 | printf("Failed to connect"); 18 | exit(1); 19 | } 20 | 21 | res = mongo_simple_str_command( conn, "test", "$eval", 22 | "for(i=0; i<100000; i++) { db.foo.find() }", &b ); 23 | 24 | ASSERT( res == MONGO_OK ); 25 | 26 | /* 50ms timeout */ 27 | mongo_set_op_timeout( conn, 50 ); 28 | 29 | ASSERT( conn->err == 0 ); 30 | res = mongo_simple_str_command( conn, "test", "$eval", 31 | "for(i=0; i<100000; i++) { db.foo.find() }", &b ); 32 | 33 | ASSERT( res == MONGO_ERROR ); 34 | ASSERT( conn->err == MONGO_IO_ERROR ); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # mongo_fdw/Makefile 2 | # 3 | # Copyright (c) 2012-2014 Citus Data, Inc. 4 | # 5 | 6 | MODULE_big = mongo_fdw 7 | 8 | # 9 | # We assume we are running on a POSIX compliant system (Linux, OSX). If you are 10 | # on another platform, change env_posix.os in MONGO_OBJS with the appropriate 11 | # environment object file. 12 | # 13 | 14 | MONGO_DRIVER = mongo-c-driver-v0.6 15 | MONGO_PATH = $(MONGO_DRIVER)/src 16 | MONGO_OBJS = $(MONGO_PATH)/bson.os $(MONGO_PATH)/encoding.os $(MONGO_PATH)/md5.os \ 17 | $(MONGO_PATH)/mongo.os $(MONGO_PATH)/numbers.os $(MONGO_PATH)/env_posix.os 18 | 19 | PG_CPPFLAGS = --std=c99 -I$(MONGO_PATH) 20 | OBJS = mongo_fdw.o mongo_query.o $(MONGO_OBJS) 21 | 22 | EXTENSION = mongo_fdw 23 | DATA = mongo_fdw--1.0.sql 24 | 25 | $(MONGO_DRIVER)/%.os: 26 | $(MAKE) -C $(MONGO_DRIVER) $*.os 27 | 28 | # 29 | # Users need to specify their Postgres installation path through pg_config. For 30 | # example: /usr/local/pgsql/bin/pg_config or /usr/lib/postgresql/9.1/bin/pg_config 31 | # 32 | 33 | PG_CONFIG = pg_config 34 | PGXS := $(shell $(PG_CONFIG) --pgxs) 35 | include $(PGXS) 36 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/resize_test.c: -------------------------------------------------------------------------------- 1 | /* resize.c */ 2 | 3 | #include "test.h" 4 | #include "bson.h" 5 | #include 6 | 7 | /* 64 Xs */ 8 | const char *bigstring = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; 9 | 10 | int main() { 11 | bson b; 12 | 13 | bson_init( &b ); 14 | bson_append_string( &b, "a", bigstring ); 15 | bson_append_start_object( &b, "sub" ); 16 | bson_append_string( &b,"a", bigstring ); 17 | bson_append_start_object( &b, "sub" ); 18 | bson_append_string( &b,"a", bigstring ); 19 | bson_append_start_object( &b, "sub" ); 20 | bson_append_string( &b,"a", bigstring ); 21 | bson_append_string( &b,"b", bigstring ); 22 | bson_append_string( &b,"c", bigstring ); 23 | bson_append_string( &b,"d", bigstring ); 24 | bson_append_string( &b,"e", bigstring ); 25 | bson_append_string( &b,"f", bigstring ); 26 | bson_append_finish_object( &b ); 27 | bson_append_finish_object( &b ); 28 | bson_append_finish_object( &b ); 29 | bson_finish( &b ); 30 | 31 | /* bson_print(&b); */ 32 | bson_destroy( &b ); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/commands_test.c: -------------------------------------------------------------------------------- 1 | /* commands_test.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include 6 | #include 7 | #include 8 | 9 | int main() { 10 | mongo conn[1]; 11 | bson cmd[1]; 12 | bson out[1]; 13 | bson_iterator it[1]; 14 | 15 | const char *db = "test"; 16 | const char *col = "c.capped"; 17 | 18 | INIT_SOCKETS_FOR_WINDOWS; 19 | 20 | if ( mongo_connect( conn , TEST_SERVER , 27017 ) ) { 21 | printf( "failed to connect\n" ); 22 | exit( 1 ); 23 | } 24 | 25 | mongo_cmd_drop_collection( conn, db, col, NULL ); 26 | 27 | ASSERT( mongo_create_capped_collection( conn, db, col, 28 | 1024, 100, NULL ) == MONGO_OK ); 29 | 30 | bson_init( cmd ); 31 | bson_append_string( cmd, "collstats", col ); 32 | bson_finish( cmd ); 33 | 34 | ASSERT( mongo_run_command( conn, db, cmd, out ) == MONGO_OK ); 35 | 36 | ASSERT( bson_find( it, out, "capped" ) == BSON_INT ); 37 | ASSERT( bson_find( it, out, "max" ) == BSON_INT ); 38 | 39 | mongo_cmd_drop_collection( conn, "test", col, NULL ); 40 | mongo_cmd_drop_db( conn, db ); 41 | 42 | mongo_destroy( conn ); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/bson_subobject_test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "bson.h" 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | bson_iterator it[1], it2[1]; 9 | bson b[1]; 10 | bson sub[1]; 11 | bson copy[1]; 12 | bson_type type; 13 | 14 | bson_init( b ); 15 | bson_append_string( b, "foo", "hello" ); 16 | 17 | { 18 | bson_append_start_object( b, "o" ); 19 | bson_append_string( b, "bar", "goodbye" ); 20 | bson_append_finish_object( b ); 21 | } 22 | 23 | bson_iterator_init( it, b ); 24 | 25 | bson_iterator_next( it ); 26 | type = bson_iterator_next( it ); 27 | 28 | ASSERT( BSON_OBJECT == type ); 29 | 30 | bson_iterator_subobject( it, sub ); 31 | ASSERT( sub->finished == 1 ); 32 | 33 | bson_iterator_init( it2, sub ); 34 | 35 | type = bson_iterator_next( it2 ); 36 | ASSERT( BSON_STRING == type ); 37 | type = bson_iterator_next( it2 ); 38 | ASSERT( BSON_EOO == type ); 39 | 40 | bson_copy( copy, sub ); 41 | 42 | ASSERT( 1 == copy->finished ); 43 | ASSERT( 0 == copy->stackPos ); 44 | ASSERT( 0 == copy->err ); 45 | 46 | bson_destroy( b ); 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/helpers_test.c: -------------------------------------------------------------------------------- 1 | /* helpers.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void test_index_helper( mongo *conn ) { 11 | 12 | bson b, out; 13 | bson_iterator it; 14 | 15 | bson_init( &b ); 16 | bson_append_int( &b, "foo", 1 ); 17 | bson_finish( &b ); 18 | 19 | mongo_create_index( conn, "test.bar", &b, MONGO_INDEX_SPARSE | MONGO_INDEX_UNIQUE, &out ); 20 | 21 | bson_destroy( &b ); 22 | 23 | bson_init( &b ); 24 | bson_append_start_object( &b, "key" ); 25 | bson_append_int( &b, "foo", 1 ); 26 | bson_append_finish_object( &b ); 27 | 28 | bson_finish( &b ); 29 | 30 | mongo_find_one( conn, "test.system.indexes", &b, NULL, &out ); 31 | 32 | bson_print( &out ); 33 | 34 | bson_iterator_init( &it, &out ); 35 | 36 | ASSERT( bson_find( &it, &out, "unique" ) ); 37 | ASSERT( bson_find( &it, &out, "sparse" ) ); 38 | } 39 | 40 | int main() { 41 | 42 | mongo conn[1]; 43 | 44 | INIT_SOCKETS_FOR_WINDOWS; 45 | 46 | if( mongo_connect( conn, TEST_SERVER, 27017 ) != MONGO_OK ) { 47 | printf( "Failed to connect" ); 48 | exit( 1 ); 49 | } 50 | 51 | 52 | test_index_helper( conn ); 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/cpptest.cpp: -------------------------------------------------------------------------------- 1 | #include "mongo.h" 2 | #include "test.h" 3 | #include 4 | #include 5 | #include 6 | 7 | // this is just a simple test to make sure everything works when compiled with a c++ compiler 8 | 9 | using namespace std; 10 | 11 | int main(){ 12 | mongo conn[1]; 13 | bson b; 14 | 15 | INIT_SOCKETS_FOR_WINDOWS; 16 | 17 | if (mongo_connect( conn, TEST_SERVER, 27017 )){ 18 | cout << "failed to connect" << endl; 19 | return 1; 20 | } 21 | 22 | for(int i=0; i< 5; i++){ 23 | bson_init( &b ); 24 | 25 | bson_append_new_oid( &b, "_id" ); 26 | bson_append_double( &b , "a" , 17 ); 27 | bson_append_int( &b , "b" , 17 ); 28 | bson_append_string( &b , "c" , "17" ); 29 | 30 | { 31 | bson_append_start_object( &b , "d" ); 32 | bson_append_int( &b, "i", 71 ); 33 | bson_append_finish_object( &b ); 34 | } 35 | { 36 | bson_append_start_array( &b , "e" ); 37 | bson_append_int( &b, "0", 71 ); 38 | bson_append_string( &b, "1", "71" ); 39 | bson_append_finish_object( &b ); 40 | } 41 | 42 | bson_finish(&b); 43 | bson_destroy(&b); 44 | } 45 | 46 | mongo_destroy( conn ); 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/source/index.rst: -------------------------------------------------------------------------------- 1 | MongoDB C Driver Documentation 2 | ============================== 3 | 4 | Overview 5 | -------- 6 | 7 | The MongoDB C Driver is a 10gen-supported driver for MongoDB. 8 | It's written in pure C. The goal is to be super strict for ultimate 9 | portability, no dependencies, and generic embeddability. 10 | 11 | The driver is still considered alpha but is undergoing active 12 | development. Support for replica sets was just added in v0.3.1. 13 | The API was completely revamped in v0.4. Another backward-breaking 14 | change (support for `write_concern`) was added in v0.6. 15 | 16 | :doc:`tutorial` 17 | An overview of the driver's API. 18 | 19 | :doc:`building` 20 | How to build the driver from source. 21 | 22 | :doc:`bson` 23 | How to work with BSON objects. 24 | 25 | :doc:`connections` 26 | How to connect to single nodes and to replica sets. 27 | 28 | :doc:`write_concern` 29 | How to detect write errors and ensure various durability levels. 30 | 31 | :doc:`errors` 32 | How errors are reported. 33 | 34 | `API Docs `_ 35 | Doxygen-generated API docs. 36 | 37 | `Source code `_ 38 | The source code is hosted on GitHub. 39 | 40 | .. toctree:: 41 | :maxdepth: 2 42 | 43 | tutorial 44 | building 45 | bson 46 | connections 47 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/src/env.h: -------------------------------------------------------------------------------- 1 | /** @file env.h */ 2 | 3 | /* Copyright 2009-2012 10gen Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* Header for generic net.h */ 19 | #ifndef MONGO_ENV_H_ 20 | #define MONGO_ENV_H_ 21 | 22 | #include "mongo.h" 23 | 24 | MONGO_EXTERN_C_START 25 | 26 | /* This is a no-op in the generic implementation. */ 27 | int mongo_env_set_socket_op_timeout( mongo *conn, int millis ); 28 | int mongo_env_read_socket( mongo *conn, void *buf, int len ); 29 | int mongo_env_write_socket( mongo *conn, const void *buf, int len ); 30 | int mongo_env_socket_connect( mongo *conn, const char *host, int port ); 31 | 32 | /* Initialize socket services */ 33 | MONGO_EXPORT int mongo_env_sock_init( void ); 34 | 35 | /* Close a socket */ 36 | MONGO_EXPORT int mongo_env_close_socket( int socket ); 37 | 38 | MONGO_EXTERN_C_END 39 | #endif 40 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/buildscripts/docs.py: -------------------------------------------------------------------------------- 1 | """Build the C client docs. 2 | """ 3 | 4 | from __future__ import with_statement 5 | import os 6 | import shutil 7 | import socket 8 | import subprocess 9 | import time 10 | import urllib2 11 | 12 | def clean_dir(dir): 13 | try: 14 | shutil.rmtree(dir) 15 | except: 16 | pass 17 | os.makedirs(dir) 18 | 19 | def gen_api(dir): 20 | clean_dir(dir) 21 | clean_dir("docs/source/doxygen") 22 | 23 | with open(os.devnull, 'w') as null: 24 | subprocess.call(["doxygen", "doxygenConfig"], stdout=null, stderr=null) 25 | 26 | os.rename("docs/source/doxygen/html", dir) 27 | 28 | def gen_sphinx(dir): 29 | clean_dir(dir) 30 | os.chdir("docs/source/sphinx") 31 | 32 | with open(os.devnull, 'w') as null: 33 | subprocess.call(["make", "html"], stdout=null, stderr=null) 34 | 35 | os.chdir("../../../") 36 | os.rename("docs/source/sphinx/build/html", dir) 37 | 38 | def version(): 39 | """Get the driver version from doxygenConfig. 40 | """ 41 | with open("doxygenConfig") as f: 42 | for line in f.readlines(): 43 | if line.startswith("PROJECT_NUMBER"): 44 | return line.split("=")[1].strip() 45 | 46 | 47 | def main(): 48 | print("Generating Sphinx docs in docs/html") 49 | gen_sphinx("docs/html") 50 | print("Generating Doxygen docs in docs/html/api") 51 | gen_api("docs/html/api") 52 | 53 | 54 | if __name__ == "__main__": 55 | main() 56 | 57 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/test.h: -------------------------------------------------------------------------------- 1 | #include "mongo.h" 2 | #include 3 | 4 | #define ASSERT(x) \ 5 | do{ \ 6 | if(!(x)){ \ 7 | printf("\nFailed ASSERT [%s] (%d):\n %s\n\n", __FILE__, __LINE__, #x); \ 8 | exit(1); \ 9 | }\ 10 | }while(0) 11 | 12 | #define ASSERT_EQUAL_STRINGS(x, y) \ 13 | do{ \ 14 | if((strncmp( x, y, strlen( y ) ) != 0 )){ \ 15 | printf("\nFailed ASSERT_EQUAL_STRINGS [%s] (%d):\n \"%s\" does not equal\n %s\n", __FILE__, __LINE__, x, #y); \ 16 | exit(1); \ 17 | }\ 18 | }while(0) 19 | 20 | #ifdef _WIN32 21 | #define INIT_SOCKETS_FOR_WINDOWS mongo_init_sockets(); 22 | #else 23 | #define INIT_SOCKETS_FOR_WINDOWS do {} while(0) 24 | #endif 25 | 26 | const char *TEST_DB = "test"; 27 | const char *TEST_COL = "foo"; 28 | const char *TEST_NS = "test.foo"; 29 | 30 | MONGO_EXTERN_C_START 31 | 32 | int mongo_get_server_version( char *version ) { 33 | mongo conn[1]; 34 | bson cmd[1], out[1]; 35 | bson_iterator it[1]; 36 | const char *result; 37 | 38 | mongo_connect( conn, TEST_SERVER, 27017 ); 39 | 40 | bson_init( cmd ); 41 | bson_append_int( cmd, "buildinfo", 1 ); 42 | bson_finish( cmd ); 43 | 44 | if( mongo_run_command( conn, "admin", cmd, out ) == MONGO_ERROR ) { 45 | return -1; 46 | } 47 | 48 | bson_iterator_init( it, out ); 49 | result = bson_iterator_string( it ); 50 | 51 | memcpy( version, result, strlen( result ) ); 52 | 53 | return 0; 54 | } 55 | 56 | MONGO_EXTERN_C_END 57 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/count_delete_test.c: -------------------------------------------------------------------------------- 1 | /* count_delete.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include 6 | #include 7 | #include 8 | 9 | int main() { 10 | mongo conn[1]; 11 | bson b; 12 | int i; 13 | 14 | const char *db = "test"; 15 | const char *col = "c.simple"; 16 | const char *ns = "test.c.simple"; 17 | 18 | INIT_SOCKETS_FOR_WINDOWS; 19 | 20 | if ( mongo_connect( conn , TEST_SERVER , 27017 ) ) { 21 | printf( "failed to connect\n" ); 22 | exit( 1 ); 23 | } 24 | 25 | /* if the collection doesn't exist dropping it will fail */ 26 | if ( !mongo_cmd_drop_collection( conn, "test", col, NULL ) 27 | && mongo_count( conn, db, col, NULL ) != 0 ) { 28 | printf( "failed to drop collection\n" ); 29 | exit( 1 ); 30 | } 31 | 32 | for( i=0; i< 5; i++ ) { 33 | bson_init( &b ); 34 | 35 | bson_append_new_oid( &b, "_id" ); 36 | bson_append_int( &b , "a" , i+1 ); /* 1 to 5 */ 37 | bson_finish( &b ); 38 | 39 | mongo_insert( conn , ns , &b, NULL ); 40 | bson_destroy( &b ); 41 | } 42 | 43 | /* query: {a: {$gt: 3}} */ 44 | bson_init( &b ); 45 | { 46 | bson_append_start_object( &b, "a" ); 47 | bson_append_int( &b, "$gt", 3 ); 48 | bson_append_finish_object( &b ); 49 | } 50 | bson_finish( &b ); 51 | 52 | ASSERT( mongo_count( conn, db, col, NULL ) == 5 ); 53 | ASSERT( mongo_count( conn, db, col, &b ) == 2 ); 54 | 55 | mongo_remove( conn, ns, &b, NULL ); 56 | 57 | ASSERT( mongo_count( conn, db, col, NULL ) == 3 ); 58 | ASSERT( mongo_count( conn, db, col, &b ) == 0 ); 59 | 60 | bson_destroy( &b ); 61 | mongo_cmd_drop_db( conn, db ); 62 | mongo_destroy( conn ); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/examples_test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "bson.h" 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | bson b, sub; 9 | bson_iterator it; 10 | 11 | /* Create a rich document like this one: 12 | * 13 | * { _id: ObjectId("4d95ea712b752328eb2fc2cc"), 14 | * user_id: ObjectId("4d95ea712b752328eb2fc2cd"), 15 | * 16 | * items: [ 17 | * { sku: "col-123", 18 | * name: "John Coltrane: Impressions", 19 | * price: 1099, 20 | * }, 21 | * 22 | * { sku: "young-456", 23 | * name: "Larry Young: Unity", 24 | * price: 1199 25 | * } 26 | * ], 27 | * 28 | * address: { 29 | * street: "59 18th St.", 30 | * zip: 10010 31 | * }, 32 | * 33 | * total: 2298 34 | * } 35 | */ 36 | bson_init( &b ); 37 | bson_append_new_oid( &b, "_id" ); 38 | bson_append_new_oid( &b, "user_id" ); 39 | 40 | bson_append_start_array( &b, "items" ); 41 | bson_append_start_object( &b, "0" ); 42 | bson_append_string( &b, "name", "John Coltrane: Impressions" ); 43 | bson_append_int( &b, "price", 1099 ); 44 | bson_append_finish_object( &b ); 45 | 46 | bson_append_start_object( &b, "1" ); 47 | bson_append_string( &b, "name", "Larry Young: Unity" ); 48 | bson_append_int( &b, "price", 1199 ); 49 | bson_append_finish_object( &b ); 50 | bson_append_finish_object( &b ); 51 | 52 | bson_append_start_object( &b, "address" ); 53 | bson_append_string( &b, "street", "59 18th St." ); 54 | bson_append_int( &b, "zip", 10010 ); 55 | bson_append_finish_object( &b ); 56 | 57 | bson_append_int( &b, "total", 2298 ); 58 | 59 | bson_finish( &b ); 60 | 61 | /* Advance to the 'items' array */ 62 | bson_find( &it, &b, "items" ); 63 | 64 | /* Get the subobject representing items */ 65 | bson_iterator_subobject( &it, &sub ); 66 | 67 | /* Now iterate that object */ 68 | bson_print( &sub ); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/src/encoding.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2012 10gen, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BSON_ENCODING_H_ 18 | #define BSON_ENCODING_H_ 19 | 20 | MONGO_EXTERN_C_START 21 | 22 | /** 23 | * Check that a field name is valid UTF8, does not start with a '$', 24 | * and contains no '.' characters. Set bson bit field appropriately. 25 | * Note that we don't need to check for '\0' because we're using 26 | * strlen(3), which stops at '\0'. 27 | * 28 | * @param b The bson object to which field name will be appended. 29 | * @param string The field name as char*. 30 | * @param length The length of the field name. 31 | * 32 | * @return BSON_OK if valid UTF8 and BSON_ERROR if not. All BSON strings must be 33 | * valid UTF8. This function will also check whether the string 34 | * contains '.' or starts with '$', since the validity of this depends on context. 35 | * Set the value of b->err appropriately. 36 | */ 37 | int bson_check_field_name( bson *b, const char *string, 38 | const int length ); 39 | 40 | /** 41 | * Check that a string is valid UTF8. Sets the buffer bit field appropriately. 42 | * 43 | * @param b The bson object to which string will be appended. 44 | * @param string The string to check. 45 | * @param length The length of the string. 46 | * 47 | * @return BSON_OK if valid UTF-8; otherwise, BSON_ERROR. 48 | * Sets b->err on error. 49 | */ 50 | bson_bool_t bson_check_string( bson *b, const char *string, 51 | const int length ); 52 | 53 | MONGO_EXTERN_C_END 54 | #endif 55 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/README.md: -------------------------------------------------------------------------------- 1 | # MongoDB C Driver 2 | 3 | This is then 10gen-supported MongoDB C driver. There are two goals for this driver. 4 | The first is to provide a strict, default compilation option for ultimate portability, 5 | no dependencies, and generic embeddability. 6 | 7 | The second is to support more advanced, platform-specific features, like socket timeout, 8 | by providing an interface for platform-specific modules. 9 | 10 | Until the 1.0 release, this driver should be considered alpha. Keep in mind that the API will be in flux until then. 11 | 12 | # Documentation 13 | 14 | Documentation exists in the project's `docs` folder. You can read the latest 15 | docs online at (http://api.mongodb.org/c/current/). 16 | 17 | The docs are built using Sphinx and Doxygen. If you have these tools installed, then 18 | you can build the docs with scons: 19 | 20 | scons docs 21 | 22 | The html docs will appear in docs/html. 23 | 24 | # Building 25 | 26 | First check out the version you want to build. *Always build from a particular tag, since HEAD may be 27 | a work in progress.* For example, to build version 0.6, run: 28 | 29 | git checkout v0.6 30 | 31 | You can then build the driver with scons: 32 | 33 | scons 34 | 35 | For more build options, see the docs. 36 | 37 | ## Running the tests 38 | Make sure that you're running mongod on 127.0.0.1 on the default port (27017). The replica set 39 | test assumes a replica set with at least three nodes running at 127.0.0.1 and starting at port 40 | 30000. Note that the driver does not recognize 'localhost' as a valid host name. 41 | 42 | To compile and run the tests: 43 | 44 | scons test 45 | 46 | # Error Handling 47 | Most functions return MONGO_OK or BSON_OK on success and MONGO_ERROR or BSON_ERROR on failure. 48 | Specific error codes and error strings are then stored in the `err` and `errstr` fields of the 49 | `mongo` and `bson` objects. It is the client's responsibility to check for errors and handle 50 | them appropriately. 51 | 52 | # ISSUES 53 | 54 | You can report bugs, request new features, and view this driver's roadmap 55 | using [JIRA](http://jira.mongodb.org/browse/CDRIVER). 56 | 57 | # CREDITS 58 | 59 | * Gergely Nagy - Non-null-terminated string support. 60 | * Josh Rotenberg - Initial Doxygen setup and a significant chunk of documentation. 61 | 62 | # LICENSE 63 | 64 | Unless otherwise specified in a source file, sources in this 65 | repository are published under the terms of the Apache License version 66 | 2.0, a copy of which is in this repository as APACHE-2.0.txt. 67 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/source/errors.rst: -------------------------------------------------------------------------------- 1 | Error Reporting 2 | =============== 3 | 4 | The MongoDB C driver reports errors from three sources: 5 | 6 | * The operating system 7 | * The MongoDB server 8 | * The driver itself -- typically user input errors 9 | 10 | The driver's API is structured such that nearly all functions 11 | return either `MONGO_OK` or `MONGO_ERROR`. When a function returns 12 | `MONGO_ERROR`, you may examine the `mongo` object to see why the 13 | error has occurred. 14 | 15 | Operating system errors 16 | ----------------------- 17 | 18 | A good example of an operating system error is a connection failure. 19 | 20 | .. code-block:: c 21 | 22 | mongo conn[1]; 23 | 24 | if ( mongo_connect( conn, "foo.example.com", 27017 ) == MONGO_ERROR ) { 25 | printf( "mongo_error_t: %d\n", conn->err ); 26 | printf( "errno (or WSAGetLastError() on Windows: %d\n", conn->errcode ); 27 | printf( "Error string: %s\n", conn->errstr ); 28 | exit( 1 ); 29 | } 30 | 31 | First, we print the `mongo_error_t` to get the general error type. Consult the `mongo_error_t 32 | definition `_ to interpret this. 33 | 34 | Next, we print the OS-level error code. On POSIX-compliant systems, this will be the value of 35 | `errno `_; 36 | on Windows, it's the value of `WSAGetLastError() `_. 37 | 38 | Finally, we print the error string, which gives is a few more details. This string may be 39 | the OS-level translation of the error code (e.g., POSIX's 40 | `strerror() `_), or it may be 41 | a string generated by the driver itself which better describes the failure. 42 | 43 | MongoDB errors 44 | -------------- 45 | 46 | MongoDB itself produces errors that may be returned to the client after any query 47 | or call to the `getlasterror` command. The code and strings for these errors 48 | are stored in the `mongo` object's `lasterrcode` and `lasterrstring`, respectively. 49 | We can force this sort of error by trying to run an invalid command: 50 | 51 | .. code-block:: c 52 | 53 | mongo conn[1]; 54 | int res; 55 | 56 | if( mongo_connect( conn, "foo.example.com", 27017 ) == MONGO_ERROR ) { 57 | exit( 1 ); 58 | } 59 | 60 | if( mongo_simple_int_command( conn, "admin", "badCommand", 1, &out ) == MONGO_ERROR ) { 61 | printf("Last error code: %d\n", conn->lasterrcode ); 62 | printf("Last error string: %s\n", conn->lasterrstr ); 63 | } 64 | 65 | 66 | Clearing errors 67 | --------------- 68 | 69 | To reset errors on the `mongo` object, run the `mongo_clear_errors` function: 70 | 71 | .. code-block:: c 72 | 73 | mongo_clear_errors( conn ); 74 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/functions_test.c: -------------------------------------------------------------------------------- 1 | /* functions.c */ 2 | 3 | #ifndef _WIN32 4 | #include "test.h" 5 | #include "mongo.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int test_value = 0; 12 | 13 | void *my_malloc( size_t size ) { 14 | test_value = 1; 15 | return malloc( size ); 16 | } 17 | 18 | void *my_realloc( void *ptr, size_t size ) { 19 | test_value = 2; 20 | return realloc( ptr, size ); 21 | } 22 | 23 | void my_free( void *ptr ) { 24 | test_value = 3; 25 | free( ptr ); 26 | } 27 | 28 | int my_printf( const char *format, ... ) { 29 | int ret = 0; 30 | test_value = 4; 31 | 32 | return ret; 33 | } 34 | 35 | int my_fprintf( FILE *fp, const char *format, ... ) { 36 | int ret = 0; 37 | test_value = 5; 38 | 39 | return ret; 40 | } 41 | 42 | int my_sprintf( char *s, const char *format, ... ) { 43 | int ret = 0; 44 | test_value = 6; 45 | 46 | return ret; 47 | } 48 | 49 | int my_errprintf( const char *format, ... ) { 50 | int ret = 0; 51 | test_value = 7; 52 | 53 | return ret; 54 | } 55 | 56 | int main() { 57 | 58 | void *ptr; 59 | char str[32]; 60 | int size = 256; 61 | 62 | ptr = bson_malloc( size ); 63 | ASSERT( test_value == 0 ); 64 | ptr = bson_realloc( ptr, size + 64 ); 65 | ASSERT( test_value == 0 ); 66 | bson_free( ptr ); 67 | ASSERT( test_value == 0 ); 68 | 69 | bson_malloc_func = my_malloc; 70 | bson_realloc_func = my_realloc; 71 | bson_free = my_free; 72 | 73 | ptr = bson_malloc( size ); 74 | ASSERT( test_value == 1 ); 75 | ptr = bson_realloc( ptr, size + 64 ); 76 | ASSERT( test_value == 2 ); 77 | bson_free( ptr ); 78 | ASSERT( test_value == 3 ); 79 | 80 | test_value = 0; 81 | 82 | bson_printf( "Test printf %d\n", test_value ); 83 | ASSERT( test_value == 0 ); 84 | bson_fprintf( stdout, "Test fprintf %d\n", test_value ); 85 | ASSERT( test_value == 0 ); 86 | bson_sprintf( str, "Test sprintf %d\n", test_value ); 87 | printf( "%s", str ); 88 | ASSERT( test_value == 0 ); 89 | bson_errprintf( "Test err %d\n", test_value ); 90 | ASSERT( test_value == 0 ); 91 | 92 | bson_printf = my_printf; 93 | bson_sprintf = my_sprintf; 94 | bson_fprintf = my_fprintf; 95 | bson_errprintf = my_errprintf; 96 | 97 | bson_printf( "Test %d\n", test_value ); 98 | ASSERT( test_value == 4 ); 99 | bson_fprintf( stdout, "Test %d\n", test_value ); 100 | ASSERT( test_value == 5 ); 101 | bson_sprintf( str, "Test %d\n", test_value ); 102 | ASSERT( test_value == 6 ); 103 | bson_printf( "Str: %s\n", str ); 104 | bson_errprintf( "Test %d\n", test_value ); 105 | ASSERT( test_value == 7 ); 106 | 107 | return 0; 108 | } 109 | #else 110 | int main() { 111 | return 0; 112 | } 113 | #endif 114 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/env_posix_test.c: -------------------------------------------------------------------------------- 1 | /* env_posix_test.c 2 | * Test posix-specific features. 3 | */ 4 | 5 | #include "test.h" 6 | #include "mongo.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /* Test read timeout by causing the 13 | * server to sleep for 10s on a query. 14 | */ 15 | int test_read_timeout( void ) { 16 | mongo conn[1]; 17 | bson b, obj, out, fields; 18 | int res; 19 | 20 | if ( mongo_connect( conn, TEST_SERVER, 27017 ) ) { 21 | printf( "failed to connect\n" ); 22 | exit( 1 ); 23 | } 24 | 25 | bson_init( &b ); 26 | bson_append_code( &b, "$where", "sleep( 10 * 1000 );"); 27 | bson_finish( &b ); 28 | 29 | bson_init( &obj ); 30 | bson_append_string( &obj, "foo", "bar"); 31 | bson_finish( &obj ); 32 | 33 | res = mongo_insert( conn, "test.foo", &obj, NULL ); 34 | 35 | /* Set the connection timeout here. */ 36 | mongo_set_op_timeout( conn, 1000 ); 37 | 38 | res = mongo_find_one( conn, "test.foo", &b, bson_empty(&fields), &out ); 39 | ASSERT( res == MONGO_ERROR ); 40 | 41 | ASSERT( conn->err == MONGO_IO_ERROR ); 42 | ASSERT( strcmp( "Resource temporarily unavailable", conn->errstr ) == 0 ); 43 | 44 | return 0; 45 | } 46 | 47 | /* Test getaddrinfo() by successfully connecting to 'localhost'. */ 48 | int test_getaddrinfo( void ) { 49 | mongo conn[1]; 50 | bson b[1]; 51 | char *ns = "test.foo"; 52 | 53 | if( mongo_connect( conn, "localhost", 27017 ) != MONGO_OK ) { 54 | printf( "failed to connect\n" ); 55 | exit( 1 ); 56 | } 57 | 58 | mongo_cmd_drop_collection( conn, "test", "foo", NULL ); 59 | 60 | bson_init( b ); 61 | bson_append_int( b, "foo", 17 ); 62 | bson_finish( b ); 63 | 64 | mongo_insert( conn , ns , b, NULL ); 65 | 66 | ASSERT( mongo_count( conn, "test", "foo", NULL ) == 1 ); 67 | 68 | bson_destroy( b ); 69 | mongo_destroy( conn ); 70 | 71 | 72 | return 0; 73 | } 74 | 75 | int test_error_messages( void ) { 76 | mongo conn[1]; 77 | bson b[1]; 78 | const char *ns = "test.foo"; 79 | 80 | mongo_init( conn ); 81 | 82 | bson_init( b ); 83 | bson_append_int( b, "foo", 17 ); 84 | bson_finish( b ); 85 | 86 | ASSERT( mongo_insert( conn, ns, b, NULL ) != MONGO_OK ); 87 | ASSERT( conn->err == MONGO_IO_ERROR ); 88 | ASSERT( conn->errcode == ENOTSOCK ); 89 | 90 | mongo_init( conn ); 91 | 92 | ASSERT( mongo_count( conn, "test", "foo", NULL ) == MONGO_ERROR ); 93 | ASSERT( conn->err == MONGO_IO_ERROR ); 94 | ASSERT( conn->errcode == ENOTSOCK ); 95 | 96 | return 0; 97 | } 98 | 99 | int main() { 100 | char version[10]; 101 | 102 | if( mongo_get_server_version( version ) != -1 && version[0] != '1' ) { 103 | test_read_timeout(); 104 | } 105 | test_getaddrinfo(); 106 | test_error_messages(); 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to `mongo_fdw` 2 | =========================== 3 | 4 | Following these guidelines helps to facilitate relevant discussion in pull 5 | requests and issues so the developers managing and developing this open source 6 | project can address patches and bugs as efficiently as possible. 7 | 8 | 9 | Using Issues 10 | ------------ 11 | 12 | `mongo_fdw`'s maintainers prefer that bug reports, feature requests, and pull 13 | requests are submitted as [GitHub Issues][1]. If you think you require personal 14 | assistance, please **do not** open an issue: email `engage` `@` `citusdata.com` 15 | instead. 16 | 17 | 18 | Bug Reports 19 | ----------- 20 | 21 | Before opening a bug report: 22 | 23 | 1. Search for a duplicate issue using GitHub's issue search 24 | 2. Check whethe the bug remains in the lasest `master` or `develop` commit 25 | 3. Create a reduced test case: remove code and data not relevant to the bug 26 | 27 | A contributor should be able to begin work on your bug without asking too many 28 | followup questions. If you include the following information, your bug will be 29 | serviced more quickly: 30 | 31 | * Short, descriptive title 32 | * Your OS 33 | * Versions of dependencies 34 | * Any custom modifications 35 | 36 | Once the background information is out of the way, you are free to present the 37 | bug itself. You should explain: 38 | 39 | * Steps you took to exercise the bug 40 | * The expected outcome 41 | * What actually occurred 42 | 43 | 44 | Feature Requests 45 | ---------------- 46 | 47 | We are open to adding features but ultimately control the scope and aims of the 48 | project. If a proposed feature is likely to incur high testing, maintenance, or 49 | performance costs it is also unlikely to be accepted. If a _strong_ case exists 50 | for a given feature, we may be persuaded on merit. Be specific. 51 | 52 | 53 | Pull Requests 54 | ------------- 55 | 56 | Well-constructed pull requests are very welcome. By _well-constructed_, we mean 57 | they do not introduce unrelated changes or break backwards compatibility. Just 58 | fork this repo and open a request against `develop`. 59 | 60 | Some examples of things likely to increase the likelihood a pull request is 61 | rejected: 62 | 63 | * Large structural changes, including: 64 | * Refactoring for its own sake 65 | * Adding languages to the project 66 | * Unnecesary whitespace changes 67 | * Deviation from obvious conventions 68 | * Introduction of incompatible intellectual property 69 | 70 | Please do not change version numbers in your pull request: they will be updated 71 | by the project owners prior to the next release. 72 | 73 | 74 | License 75 | ------- 76 | 77 | By submitting a patch, you agree to allow the project owners to license your 78 | work under the terms of the [`LICENSE`][2]. Additionally, you grant the project 79 | owners a license under copyright covering your contribution to the extent 80 | permitted by law. Finally, you confirm that you own said copyright, have the 81 | legal authority to grant said license, and in doing so are not violating any 82 | grant of rights you have made to third parties, including your employer. 83 | 84 | [1]: https://github.com/citusdata/mongo_fdw/issues 85 | [2]: LICENSE 86 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/update_test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "mongo.h" 3 | #include 4 | #include 5 | #include 6 | 7 | int main() { 8 | mongo conn[1]; 9 | bson obj; 10 | bson cond; 11 | int i; 12 | bson_oid_t oid; 13 | const char *col = "c.update_test"; 14 | const char *ns = "test.c.update_test"; 15 | 16 | INIT_SOCKETS_FOR_WINDOWS; 17 | 18 | if ( mongo_connect( conn , TEST_SERVER, 27017 ) ) { 19 | printf( "failed to connect\n" ); 20 | exit( 1 ); 21 | } 22 | 23 | /* if the collection doesn't exist dropping it will fail */ 24 | if ( mongo_cmd_drop_collection( conn, "test", col, NULL ) == MONGO_OK 25 | && mongo_find_one( conn, ns, bson_empty( &obj ), bson_empty( &obj ), NULL ) != MONGO_OK ) { 26 | printf( "failed to drop collection\n" ); 27 | exit( 1 ); 28 | } 29 | 30 | bson_oid_gen( &oid ); 31 | 32 | { 33 | /* insert */ 34 | bson_init( &obj ); 35 | bson_append_oid( &obj, "_id", &oid ); 36 | bson_append_int( &obj, "a", 3 ); 37 | bson_finish( &obj ); 38 | mongo_insert( conn, ns, &obj, NULL ); 39 | bson_destroy( &obj ); 40 | } 41 | 42 | { 43 | /* insert */ 44 | bson op; 45 | 46 | bson_init( &cond ); 47 | bson_append_oid( &cond, "_id", &oid ); 48 | bson_finish( &cond ); 49 | 50 | bson_init( &op ); 51 | { 52 | bson_append_start_object( &op, "$inc" ); 53 | bson_append_int( &op, "a", 2 ); 54 | bson_append_finish_object( &op ); 55 | } 56 | { 57 | bson_append_start_object( &op, "$set" ); 58 | bson_append_double( &op, "b", -1.5 ); 59 | bson_append_finish_object( &op ); 60 | } 61 | bson_finish( &op ); 62 | 63 | for ( i=0; i<5; i++ ) 64 | mongo_update( conn, ns, &cond, &op, 0, NULL ); 65 | 66 | /* cond is used later */ 67 | bson_destroy( &op ); 68 | } 69 | 70 | if( mongo_find_one( conn, ns, &cond, 0, &obj ) != MONGO_OK ) { 71 | printf( "Failed to find object\n" ); 72 | exit( 1 ); 73 | } else { 74 | int fields = 0; 75 | bson_iterator it; 76 | bson_iterator_init( &it, &obj ); 77 | 78 | bson_destroy( &cond ); 79 | 80 | while( bson_iterator_next( &it ) ) { 81 | switch( bson_iterator_key( &it )[0] ) { 82 | case '_': /* id */ 83 | ASSERT( bson_iterator_type( &it ) == BSON_OID ); 84 | ASSERT( !memcmp( bson_iterator_oid( &it )->bytes, oid.bytes, 12 ) ); 85 | fields++; 86 | break; 87 | case 'a': 88 | ASSERT( bson_iterator_type( &it ) == BSON_INT ); 89 | ASSERT( bson_iterator_int( &it ) == 3 + 5*2 ); 90 | fields++; 91 | break; 92 | case 'b': 93 | ASSERT( bson_iterator_type( &it ) == BSON_DOUBLE ); 94 | ASSERT( bson_iterator_double( &it ) == -1.5 ); 95 | fields++; 96 | break; 97 | } 98 | } 99 | 100 | ASSERT( fields == 3 ); 101 | } 102 | 103 | bson_destroy( &obj ); 104 | 105 | mongo_cmd_drop_db( conn, "test" ); 106 | mongo_destroy( conn ); 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/env_win32_test.c: -------------------------------------------------------------------------------- 1 | /* env_win32_test.c 2 | * Test WIN32-dependent features. 3 | */ 4 | 5 | #include "test.h" 6 | #include "mongo.h" 7 | #include 8 | #include 9 | #include 10 | 11 | #ifdef _MSC_VER 12 | #include // send,recv,socklen_t etc 13 | #include // addrinfo 14 | #else 15 | #include 16 | #include 17 | typedef int socklen_t; 18 | #endif 19 | 20 | /* Test read timeout by causing the 21 | * server to sleep for 10s on a query. 22 | */ 23 | int test_read_timeout( void ) { 24 | mongo conn[1]; 25 | bson b, obj, out, fields; 26 | int res; 27 | 28 | if ( mongo_connect( conn, TEST_SERVER, 27017 ) ) { 29 | printf( "failed to connect\n" ); 30 | exit( 1 ); 31 | } 32 | 33 | bson_init( &b ); 34 | bson_append_code( &b, "$where", "sleep( 10 * 1000 );"); 35 | bson_finish( &b ); 36 | 37 | bson_init( &obj ); 38 | bson_append_string( &obj, "foo", "bar"); 39 | bson_finish( &obj ); 40 | 41 | res = mongo_insert( conn, "test.foo", &obj, NULL ); 42 | 43 | /* Set the connection timeout here. */ 44 | 45 | if( mongo_set_op_timeout( conn, 1000 ) != MONGO_OK ) { 46 | printf("Could not set socket timeout!."); 47 | exit(1); 48 | } 49 | 50 | res = mongo_find_one( conn, "test.foo", &b, bson_empty(&fields), &out ); 51 | ASSERT( res == MONGO_ERROR ); 52 | 53 | ASSERT( conn->err == MONGO_IO_ERROR ); 54 | ASSERT( conn->errcode == WSAETIMEDOUT ); 55 | 56 | return 0; 57 | } 58 | 59 | /* Test getaddrinfo() by successfully connecting to 'localhost'. */ 60 | int test_getaddrinfo( void ) { 61 | mongo conn[1]; 62 | bson b[1]; 63 | const char *ns = "test.foo"; 64 | const char *errmsg = "getaddrinfo failed"; 65 | 66 | if( mongo_connect( conn, "badhost", 27017 ) == MONGO_OK ) { 67 | printf( "connected to bad host!\n" ); 68 | exit( 1 ); 69 | } else { 70 | ASSERT( strncmp( errmsg, conn->errstr, strlen( errmsg ) ) == 0 ); 71 | } 72 | 73 | 74 | if( mongo_connect( conn, "localhost", 27017 ) != MONGO_OK ) { 75 | printf( "failed to connect\n" ); 76 | exit( 1 ); 77 | } 78 | 79 | mongo_cmd_drop_collection( conn, "test", "foo", NULL ); 80 | 81 | bson_init( b ); 82 | bson_append_int( b, "foo", 17 ); 83 | bson_finish( b ); 84 | 85 | mongo_insert( conn , ns , b, NULL ); 86 | 87 | ASSERT( mongo_count( conn, "test", "foo", NULL ) == 1 ); 88 | 89 | bson_destroy( b ); 90 | mongo_destroy( conn ); 91 | 92 | 93 | return 0; 94 | } 95 | 96 | int test_error_messages( void ) { 97 | mongo conn[1]; 98 | bson b[1]; 99 | const char *ns = "test.foo"; 100 | 101 | mongo_init( conn ); 102 | 103 | bson_init( b ); 104 | bson_append_int( b, "foo", 17 ); 105 | bson_finish( b ); 106 | 107 | ASSERT( mongo_insert( conn, ns, b, NULL ) != MONGO_OK ); 108 | ASSERT( conn->err == MONGO_IO_ERROR ); 109 | ASSERT( conn->errcode == WSAENOTSOCK ); 110 | 111 | mongo_init( conn ); 112 | 113 | ASSERT( mongo_count( conn, "test", "foo", NULL ) == MONGO_ERROR ); 114 | ASSERT( conn->err == MONGO_IO_ERROR ); 115 | ASSERT( conn->errcode == WSAENOTSOCK ); 116 | 117 | return 0; 118 | } 119 | 120 | int main() { 121 | char version[10]; 122 | INIT_SOCKETS_FOR_WINDOWS; 123 | 124 | if( mongo_get_server_version( version ) != -1 && version[0] != '1' ) { 125 | test_read_timeout(); 126 | } 127 | test_getaddrinfo(); 128 | test_error_messages(); 129 | 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/examples/example.c: -------------------------------------------------------------------------------- 1 | #include "mongo.h" 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | bson b, sub, out, empty; 8 | bson_iterator it; 9 | mongo conn; 10 | mongo_cursor cursor; 11 | int result; 12 | 13 | /* Create a rich document like this one: 14 | * 15 | * { _id: ObjectId("4d95ea712b752328eb2fc2cc"), 16 | * user_id: ObjectId("4d95ea712b752328eb2fc2cd"), 17 | * 18 | * items: [ 19 | * { sku: "col-123", 20 | * name: "John Coltrane: Impressions", 21 | * price: 1099, 22 | * }, 23 | * 24 | * { sku: "young-456", 25 | * name: "Larry Young: Unity", 26 | * price: 1199 27 | * } 28 | * ], 29 | * 30 | * address: { 31 | * street: "59 18th St.", 32 | * zip: 10010 33 | * }, 34 | * 35 | * total: 2298 36 | * } 37 | */ 38 | bson_init( &b ); 39 | bson_append_new_oid( &b, "_id" ); 40 | bson_append_new_oid( &b, "user_id" ); 41 | 42 | bson_append_start_array( &b, "items" ); 43 | bson_append_start_object( &b, "0" ); 44 | bson_append_string( &b, "name", "John Coltrane: Impressions" ); 45 | bson_append_int( &b, "price", 1099 ); 46 | bson_append_finish_object( &b ); 47 | 48 | bson_append_start_object( &b, "1" ); 49 | bson_append_string( &b, "name", "Larry Young: Unity" ); 50 | bson_append_int( &b, "price", 1199 ); 51 | bson_append_finish_object( &b ); 52 | bson_append_finish_object( &b ); 53 | 54 | bson_append_start_object( &b, "address" ); 55 | bson_append_string( &b, "street", "59 18th St." ); 56 | bson_append_int( &b, "zip", 10010 ); 57 | bson_append_finish_object( &b ); 58 | 59 | bson_append_int( &b, "total", 2298 ); 60 | 61 | /* Finish the BSON obj. */ 62 | bson_finish( &b ); 63 | printf("Here's the whole BSON object:\n"); 64 | bson_print( &b ); 65 | 66 | /* Advance to the 'items' array */ 67 | bson_find( &it, &b, "items" ); 68 | 69 | /* Get the subobject representing items */ 70 | bson_iterator_subobject( &it, &sub ); 71 | 72 | /* Now iterate that object */ 73 | printf("And here's the inner sub-object by itself.\n"); 74 | bson_print( &sub ); 75 | 76 | /* Now make a connection to MongoDB. */ 77 | if( mongo_connect( &conn, "127.0.0.1", 27017 ) != MONGO_OK ) { 78 | switch( conn.err ) { 79 | case MONGO_CONN_NO_SOCKET: 80 | printf( "FAIL: Could not create a socket!\n" ); 81 | break; 82 | case MONGO_CONN_FAIL: 83 | printf( "FAIL: Could not connect to mongod. Make sure it's listening at 127.0.0.1:27017.\n" ); 84 | break; 85 | } 86 | 87 | exit( 1 ); 88 | } 89 | 90 | /* Insert the sample BSON document. */ 91 | if( mongo_insert( &conn, "test.records", &b ) != MONGO_OK ) { 92 | printf( "FAIL: Failed to insert document with error %d\n", conn.err ); 93 | exit( 1 ); 94 | } 95 | 96 | /* Query for the sample document. */ 97 | mongo_cursor_init( &cursor, &conn, "test.records" ); 98 | mongo_cursor_set_query( &cursor, bson_empty( &empty ) ); 99 | if( mongo_cursor_next( &cursor ) != MONGO_OK ) { 100 | printf( "FAIL: Failed to find inserted document." ); 101 | exit( 1 ); 102 | } 103 | 104 | printf( "Found saved BSON object:\n" ); 105 | bson_print( (bson *)mongo_cursor_bson( &cursor ) ); 106 | 107 | mongo_cmd_drop_collection( &conn, "test", "records", NULL ); 108 | mongo_cursor_destroy( &cursor ); 109 | bson_destroy( &b ); 110 | mongo_destroy( &conn ); 111 | 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/src/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ 25 | /* 26 | Independent implementation of MD5 (RFC 1321). 27 | 28 | This code implements the MD5 Algorithm defined in RFC 1321, whose 29 | text is available at 30 | http://www.ietf.org/rfc/rfc1321.txt 31 | The code is derived from the text of the RFC, including the test suite 32 | (section A.5) but excluding the rest of Appendix A. It does not include 33 | any code or documentation that is identified in the RFC as being 34 | copyrighted. 35 | 36 | The original and principal author of md5.h is L. Peter Deutsch 37 | . Other authors are noted in the change history 38 | that follows (in reverse chronological order): 39 | 40 | 2002-04-13 lpd Removed support for non-ANSI compilers; removed 41 | references to Ghostscript; clarified derivation from RFC 1321; 42 | now handles byte order either statically or dynamically. 43 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 44 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); 45 | added conditionalization for C++ compilation from Martin 46 | Purschke . 47 | 1999-05-03 lpd Original version. 48 | */ 49 | 50 | #ifndef MONGO_MD5_H_ 51 | #define MONGO_MD5_H_ 52 | 53 | /* 54 | * This package supports both compile-time and run-time determination of CPU 55 | * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be 56 | * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is 57 | * defined as non-zero, the code will be compiled to run only on big-endian 58 | * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to 59 | * run on either big- or little-endian CPUs, but will run slightly less 60 | * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. 61 | */ 62 | #include "bson.h" 63 | 64 | typedef unsigned char mongo_md5_byte_t; /* 8-bit byte */ 65 | typedef unsigned int mongo_md5_word_t; /* 32-bit word */ 66 | 67 | /* Define the state of the MD5 Algorithm. */ 68 | typedef struct mongo_md5_state_s { 69 | mongo_md5_word_t count[2]; /* message length in bits, lsw first */ 70 | mongo_md5_word_t abcd[4]; /* digest buffer */ 71 | mongo_md5_byte_t buf[64]; /* accumulate block */ 72 | } mongo_md5_state_t; 73 | 74 | #ifdef __cplusplus 75 | extern "C" 76 | { 77 | #endif 78 | 79 | /* Initialize the algorithm. */ 80 | MONGO_EXPORT void mongo_md5_init(mongo_md5_state_t *pms); 81 | 82 | /* Append a string to the message. */ 83 | MONGO_EXPORT void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes); 84 | 85 | /* Finish the message and return the digest. */ 86 | MONGO_EXPORT void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]); 87 | 88 | #ifdef __cplusplus 89 | } /* end extern "C" */ 90 | #endif 91 | 92 | #endif /* MONGO_MD5_H_ */ 93 | -------------------------------------------------------------------------------- /mongo_fdw.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------- 2 | * 3 | * mongo_fdw.h 4 | * 5 | * Type and function declarations for MongoDB foreign data wrapper. 6 | * 7 | * Copyright (c) 2012-2014 Citus Data, Inc. 8 | * 9 | *------------------------------------------------------------------------- 10 | */ 11 | 12 | #ifndef MONGO_FDW_H 13 | #define MONGO_FDW_H 14 | 15 | #include "bson.h" 16 | #include "mongo.h" 17 | 18 | #include "fmgr.h" 19 | #include "catalog/pg_foreign_server.h" 20 | #include "catalog/pg_foreign_table.h" 21 | #include "utils/datetime.h" 22 | #include "nodes/pg_list.h" 23 | #include "nodes/relation.h" 24 | #include "utils/timestamp.h" 25 | 26 | 27 | /* Defines for valid option names */ 28 | #define OPTION_NAME_ADDRESS "address" 29 | #define OPTION_NAME_PORT "port" 30 | #define OPTION_NAME_DATABASE "database" 31 | #define OPTION_NAME_COLLECTION "collection" 32 | 33 | /* Default values for option parameters */ 34 | #define DEFAULT_IP_ADDRESS "127.0.0.1" 35 | #define DEFAULT_PORT_NUMBER 27017 36 | #define DEFAULT_DATABASE_NAME "test" 37 | 38 | /* Defines for sending queries and converting types */ 39 | #define EQUALITY_OPERATOR_NAME "=" 40 | #define INITIAL_ARRAY_CAPACITY 8 41 | #define MONGO_TUPLE_COST_MULTIPLIER 5 42 | #define MONGO_CONNECTION_COST_MULTIPLIER 5 43 | #define POSTGRES_TO_UNIX_EPOCH_DAYS (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) 44 | #define POSTGRES_TO_UNIX_EPOCH_USECS (POSTGRES_TO_UNIX_EPOCH_DAYS * USECS_PER_DAY) 45 | 46 | 47 | /* 48 | * MongoValidOption keeps an option name and a context. When an option is passed 49 | * into mongo_fdw objects (server and foreign table), we compare this option's 50 | * name and context against those of valid options. 51 | */ 52 | typedef struct MongoValidOption 53 | { 54 | const char *optionName; 55 | Oid optionContextId; 56 | 57 | } MongoValidOption; 58 | 59 | 60 | /* Array of options that are valid for mongo_fdw */ 61 | static const uint32 ValidOptionCount = 4; 62 | static const MongoValidOption ValidOptionArray[] = 63 | { 64 | /* foreign server options */ 65 | { OPTION_NAME_ADDRESS, ForeignServerRelationId }, 66 | { OPTION_NAME_PORT, ForeignServerRelationId }, 67 | 68 | /* foreign table options */ 69 | { OPTION_NAME_DATABASE, ForeignTableRelationId }, 70 | { OPTION_NAME_COLLECTION, ForeignTableRelationId } 71 | }; 72 | 73 | 74 | /* 75 | * MongoFdwOptions holds the option values to be used when connecting to Mongo. 76 | * To resolve these values, we first check foreign table's options, and if not 77 | * present, we then fall back to the default values specified above. 78 | */ 79 | typedef struct MongoFdwOptions 80 | { 81 | char *addressName; 82 | int32 portNumber; 83 | char *databaseName; 84 | char *collectionName; 85 | 86 | } MongoFdwOptions; 87 | 88 | 89 | /* 90 | * MongoFdwExecState keeps foreign data wrapper specific execution state that we 91 | * create and hold onto when executing the query. 92 | */ 93 | typedef struct MongoFdwExecState 94 | { 95 | struct HTAB *columnMappingHash; 96 | mongo *mongoConnection; 97 | mongo_cursor *mongoCursor; 98 | bson *queryDocument; 99 | 100 | } MongoFdwExecState; 101 | 102 | 103 | /* 104 | * ColumnMapping reprents a hash table entry that maps a column name to column 105 | * related information. We construct these hash table entries to speed up the 106 | * conversion from BSON documents to PostgreSQL tuples; and each hash entry maps 107 | * the column name to the column's tuple index and its type-related information. 108 | */ 109 | typedef struct ColumnMapping 110 | { 111 | char columnName[NAMEDATALEN]; 112 | uint32 columnIndex; 113 | Oid columnTypeId; 114 | int32 columnTypeMod; 115 | Oid columnArrayTypeId; 116 | 117 | } ColumnMapping; 118 | 119 | 120 | /* Function declarations related to creating the mongo query */ 121 | extern List * ApplicableOpExpressionList(RelOptInfo *baserel); 122 | extern bson * QueryDocument(Oid relationId, List *opExpressionList); 123 | extern List * ColumnList(RelOptInfo *baserel); 124 | 125 | /* Function declarations for foreign data wrapper */ 126 | extern Datum mongo_fdw_handler(PG_FUNCTION_ARGS); 127 | extern Datum mongo_fdw_validator(PG_FUNCTION_ARGS); 128 | 129 | 130 | #endif /* MONGO_FDW_H */ 131 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/replica_set_test.c: -------------------------------------------------------------------------------- 1 | /* test.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #ifndef SEED_START_PORT 11 | #define SEED_START_PORT 30000 12 | #endif 13 | 14 | #ifndef REPLICA_SET_NAME 15 | #define REPLICA_SET_NAME "replica-set-foo" 16 | #endif 17 | 18 | int test_connect( const char *set_name ) { 19 | 20 | mongo conn[1]; 21 | int res; 22 | 23 | INIT_SOCKETS_FOR_WINDOWS; 24 | 25 | mongo_replset_init( conn, set_name ); 26 | mongo_replset_add_seed( conn, TEST_SERVER, SEED_START_PORT + 1 ); 27 | mongo_replset_add_seed( conn, TEST_SERVER, SEED_START_PORT ); 28 | 29 | res = mongo_replset_connect( conn ); 30 | 31 | if( res != MONGO_OK ) { 32 | res = conn->err; 33 | return res; 34 | } 35 | 36 | ASSERT( conn->primary->port == SEED_START_PORT || 37 | conn->primary->port == SEED_START_PORT + 1 || 38 | conn->primary->port == SEED_START_PORT + 2 ); 39 | 40 | mongo_destroy( conn ); 41 | return res; 42 | } 43 | 44 | int test_reconnect( const char *set_name ) { 45 | 46 | mongo conn[1]; 47 | int res = 0; 48 | int e = 0; 49 | bson b; 50 | 51 | INIT_SOCKETS_FOR_WINDOWS; 52 | 53 | mongo_replset_init( conn, set_name ); 54 | mongo_replset_add_seed( conn, TEST_SERVER, SEED_START_PORT ); 55 | mongo_replset_add_seed( conn, TEST_SERVER, SEED_START_PORT + 1 ); 56 | 57 | 58 | if( ( mongo_replset_connect( conn ) != MONGO_OK ) ) { 59 | mongo_destroy( conn ); 60 | return MONGO_ERROR; 61 | } else { 62 | fprintf( stderr, "Disconnect now:\n" ); 63 | sleep( 10 ); 64 | e = 1; 65 | do { 66 | res = mongo_find_one( conn, "foo.bar", bson_empty( &b ), bson_empty( &b ), NULL ); 67 | if( res == MONGO_ERROR && conn->err == MONGO_IO_ERROR ) { 68 | sleep( 2 ); 69 | if( e++ < 30 ) { 70 | fprintf( stderr, "Attempting reconnect %d.\n", e ); 71 | mongo_reconnect( conn ); 72 | } else { 73 | fprintf( stderr, "Fail.\n" ); 74 | return -1; 75 | } 76 | } 77 | } while( 1 ); 78 | } 79 | 80 | 81 | return 0; 82 | } 83 | 84 | int test_insert_limits( const char *set_name ) { 85 | char version[10]; 86 | mongo conn[1]; 87 | mongo_write_concern wc[1]; 88 | int i; 89 | char key[10]; 90 | int res = 0; 91 | bson b[1], b2[1]; 92 | bson *objs[2]; 93 | 94 | mongo_write_concern_init( wc ); 95 | wc->w = 1; 96 | mongo_write_concern_finish( wc ); 97 | 98 | /* We'll perform the full test if we're running v2.0 or later. */ 99 | if( mongo_get_server_version( version ) != -1 && version[0] <= '1' ) 100 | return 0; 101 | 102 | mongo_replset_init( conn, set_name ); 103 | mongo_replset_add_seed( conn, TEST_SERVER, SEED_START_PORT + 1 ); 104 | mongo_replset_add_seed( conn, TEST_SERVER, SEED_START_PORT ); 105 | res = mongo_replset_connect( conn ); 106 | 107 | if( res != MONGO_OK ) { 108 | res = conn->err; 109 | return res; 110 | } 111 | 112 | ASSERT( conn->max_bson_size > MONGO_DEFAULT_MAX_BSON_SIZE ); 113 | 114 | bson_init( b ); 115 | for(i=0; i<1200000; i++) { 116 | sprintf( key, "%d", i + 10000000 ); 117 | bson_append_int( b, key, i ); 118 | } 119 | bson_finish( b ); 120 | 121 | ASSERT( bson_size( b ) > conn->max_bson_size ); 122 | 123 | ASSERT( mongo_insert( conn, "test.foo", b, wc ) == MONGO_ERROR ); 124 | ASSERT( conn->err == MONGO_BSON_TOO_LARGE ); 125 | 126 | mongo_clear_errors( conn ); 127 | ASSERT( conn->err == 0 ); 128 | 129 | bson_init( b2 ); 130 | bson_append_int( b2, "foo", 1 ); 131 | bson_finish( b2 ); 132 | 133 | objs[0] = b; 134 | objs[1] = b2; 135 | 136 | ASSERT( mongo_insert_batch( conn, "test.foo", (const bson**)objs, 2, wc, 0 ) == MONGO_ERROR ); 137 | ASSERT( conn->err == MONGO_BSON_TOO_LARGE ); 138 | 139 | mongo_write_concern_destroy( wc ); 140 | 141 | return 0; 142 | } 143 | 144 | int main() { 145 | ASSERT( test_connect( REPLICA_SET_NAME ) == MONGO_OK ); 146 | ASSERT( test_connect( "test-foobar" ) == MONGO_CONN_BAD_SET_NAME ); 147 | ASSERT( test_insert_limits( REPLICA_SET_NAME ) == MONGO_OK ); 148 | 149 | /* 150 | ASSERT( test_reconnect( "test-rs" ) == 0 ); 151 | */ 152 | 153 | return 0; 154 | } 155 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/validate_test.c: -------------------------------------------------------------------------------- 1 | /* validate.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include "encoding.h" 6 | #include 7 | #include 8 | #include 9 | 10 | #define BATCH_SIZE 10 11 | 12 | static void make_small_invalid( bson *out, int i ) { 13 | bson_init( out ); 14 | bson_append_new_oid( out, "$_id" ); 15 | bson_append_int( out, "x.foo", i ); 16 | bson_finish( out ); 17 | } 18 | 19 | int main() { 20 | mongo conn[1]; 21 | bson b, empty; 22 | mongo_cursor cursor[1]; 23 | unsigned char not_utf8[3]; 24 | int result = 0; 25 | const char *ns = "test.c.validate"; 26 | 27 | int i=0, j=0; 28 | bson bs[BATCH_SIZE]; 29 | bson *bp[BATCH_SIZE]; 30 | 31 | not_utf8[0] = 0xC0; 32 | not_utf8[1] = 0xC0; 33 | not_utf8[2] = '\0'; 34 | 35 | INIT_SOCKETS_FOR_WINDOWS; 36 | 37 | if ( mongo_connect( conn, TEST_SERVER, 27017 ) ) { 38 | printf( "failed to connect\n" ); 39 | exit( 1 ); 40 | } 41 | 42 | /* Test checking for finished bson. */ 43 | bson_init( &b ); 44 | bson_append_int( &b, "foo", 1 ); 45 | ASSERT( mongo_insert( conn, "test.foo", &b, NULL ) == MONGO_ERROR ); 46 | ASSERT( conn->err == MONGO_BSON_NOT_FINISHED ); 47 | 48 | /* Test valid keys. */ 49 | bson_init( &b ); 50 | result = bson_append_string( &b , "a.b" , "17" ); 51 | ASSERT( result == BSON_OK ); 52 | 53 | ASSERT( b.err & BSON_FIELD_HAS_DOT ); 54 | 55 | /* Don't set INIT dollar if deb ref fields are being used. */ 56 | result = bson_append_string( &b , "$id" , "17" ); 57 | ASSERT( result == BSON_OK ); 58 | ASSERT( !(b.err & BSON_FIELD_INIT_DOLLAR) ); 59 | 60 | result = bson_append_string( &b , "$ref" , "17" ); 61 | ASSERT( result == BSON_OK ); 62 | ASSERT( !(b.err & BSON_FIELD_INIT_DOLLAR) ); 63 | 64 | result = bson_append_string( &b , "$db" , "17" ); 65 | ASSERT( result == BSON_OK ); 66 | ASSERT( !(b.err & BSON_FIELD_INIT_DOLLAR) ); 67 | 68 | result = bson_append_string( &b , "$ab" , "17" ); 69 | ASSERT( result == BSON_OK ); 70 | ASSERT( b.err & BSON_FIELD_INIT_DOLLAR ); 71 | 72 | result = bson_append_string( &b , "ab" , "this is valid utf8" ); 73 | ASSERT( result == BSON_OK ); 74 | ASSERT( ! ( b.err & BSON_NOT_UTF8 ) ); 75 | 76 | result = bson_append_string( &b , ( const char * )not_utf8, "valid" ); 77 | ASSERT( result == BSON_ERROR ); 78 | ASSERT( b.err & BSON_NOT_UTF8 ); 79 | 80 | ASSERT( bson_finish( &b ) == BSON_ERROR ); 81 | ASSERT( b.err & BSON_FIELD_HAS_DOT ); 82 | ASSERT( b.err & BSON_FIELD_INIT_DOLLAR ); 83 | ASSERT( b.err & BSON_NOT_UTF8 ); 84 | 85 | result = mongo_insert( conn, ns, &b, NULL ); 86 | ASSERT( result == MONGO_ERROR ); 87 | ASSERT( conn->err & MONGO_BSON_NOT_FINISHED ); 88 | 89 | result = mongo_update( conn, ns, bson_empty( &empty ), &b, 0, NULL ); 90 | ASSERT( result == MONGO_ERROR ); 91 | ASSERT( conn->err & MONGO_BSON_NOT_FINISHED ); 92 | 93 | mongo_cursor_init( cursor, conn, "test.cursors" ); 94 | mongo_cursor_set_query( cursor, &b ); 95 | result = mongo_cursor_next( cursor ); 96 | ASSERT( result == MONGO_ERROR ); 97 | ASSERT( cursor->err & MONGO_CURSOR_BSON_ERROR ); 98 | ASSERT( cursor->conn->err & MONGO_BSON_NOT_FINISHED ); 99 | 100 | bson_destroy( &b ); 101 | 102 | /* Test valid strings. */ 103 | bson_init( & b ); 104 | result = bson_append_string( &b , "foo" , "bar" ); 105 | ASSERT( result == BSON_OK ); 106 | ASSERT( b.err == 0 ); 107 | 108 | result = bson_append_string( &b , "foo" , ( const char * )not_utf8 ); 109 | ASSERT( result == BSON_ERROR ); 110 | ASSERT( b.err & BSON_NOT_UTF8 ); 111 | 112 | b.err = 0; 113 | ASSERT( b.err == 0 ); 114 | 115 | result = bson_append_regex( &b , "foo" , ( const char * )not_utf8, "s" ); 116 | ASSERT( result == BSON_ERROR ); 117 | ASSERT( b.err & BSON_NOT_UTF8 ); 118 | 119 | for ( j=0; j < BATCH_SIZE; j++ ) 120 | bp[j] = &bs[j]; 121 | 122 | for ( j=0; j < BATCH_SIZE; j++ ) 123 | make_small_invalid( &bs[j], i ); 124 | 125 | result = mongo_insert_batch( conn, ns, (const bson **)bp, BATCH_SIZE, NULL, 0 ); 126 | ASSERT( result == MONGO_ERROR ); 127 | ASSERT( conn->err == MONGO_BSON_INVALID ); 128 | 129 | for ( j=0; j < BATCH_SIZE; j++ ) 130 | bson_destroy( &bs[j] ); 131 | 132 | mongo_cmd_drop_db( conn, "test" ); 133 | mongo_disconnect( conn ); 134 | 135 | mongo_destroy( conn ); 136 | 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/source/write_concern.rst: -------------------------------------------------------------------------------- 1 | Write Concern (a.k.a. "Safe Mode") 2 | ================================== 3 | 4 | All writes issued from the drivers for MongoDB are "fire-and-forget" by default. 5 | In practice, this means that by default, failed writes aren't reported. 6 | For this reason, "fire-and-forget" writes are recommended 7 | only for cases where losing a few writes is acceptable (logging, anayltics, etc.). 8 | 9 | In all other scenarios, you should ensure that your writes run as a round trip 10 | to the server. This requires that you enable write concern or "safe mode", as it's 11 | called elsewhere. 12 | 13 | In addition to reporting write errors, write concern also allows you to ensure 14 | that your write are replicated to a particular number of servers to a set 15 | of servers tagged with a given value. See the 16 | `write concern docs `_ for details. 17 | 18 | Implementation and API 19 | ---------------------- 20 | 21 | Write concern is implemented by appending a call to the ``getlasterror`` 22 | command after each write. You can certainly do this manually, but nearly all of the drivers 23 | provide a write concern API for simplicty. To read about the options for ``getlasterror``, 24 | and hence the options for write concern, 25 | `see the MongoDB getlasterror docs `_. 26 | 27 | The MongoDB C driver supports write concern on two levels. You can set the write 28 | concern on a ``mongo`` connection object, in which case that write concern level will 29 | be used for every write. You can also specify a write concern for any individual 30 | write operation (``mongo_insert()``, ``mongo_insert_batch()``, ``mongo_update()``, 31 | or ``mongo_remove``). This will override any default write concern set on the 32 | connection level. 33 | 34 | Example 35 | ------- 36 | 37 | .. code-block:: c 38 | 39 | #include 40 | #include 41 | 42 | #define ASSERT(x) \ 43 | do{ \ 44 | if(!(x)){ \ 45 | printf("\nFailed ASSERT [%s] (%d):\n %s\n\n", __FILE__, __LINE__, #x); \ 46 | exit(1); \ 47 | }\ 48 | }while(0) 49 | 50 | int main() { 51 | mongo conn[1]; 52 | mongo_write_concern write_concern[1]; 53 | bson b[1]; 54 | 55 | if( mongo_connect( conn, "127.0.0.1", 27017 ) == MONGO_ERROR ) { 56 | printf( "Failed to connect!\n" ); 57 | exit(1); 58 | } 59 | 60 | mongo_cmd_drop_collection( conn, "test", "foo", NULL ); 61 | 62 | /* Initialize the write concern object.*/ 63 | mongo_write_concern_init( write_concern ); 64 | write_concern->w = 1; 65 | mongo_write_concern_finish( write_concern ); 66 | 67 | bson_init( b ); 68 | bson_append_new_oid( b ); 69 | bson_finish( b ); 70 | 71 | ASSERT( mongo_insert( conn, "test.foo", b, wc ) == MONGO_ERROR ); 72 | 73 | /* If we try to insert the same document again, 74 | we'll get an error due to the unique index on _id.*/ 75 | ASSERT( mongo_insert( conn, "test.foo", b, wc ) == MONGO_ERROR ); 76 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 77 | printf( "Error message: %s\n", conn->lasterrstr ); 78 | 79 | /* Clear any stored errors.*/ 80 | mongo_clear_errors( conn ); 81 | 82 | /* We'll get the same error if we set a default write concern 83 | on the connection object but don't set it on insert.*/ 84 | mongo_set_write_concern( conn, write_concern ); 85 | ASSERT( mongo_insert( conn, "test.foo", b, wc ) == MONGO_ERROR ); 86 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 87 | printf( "Error message: %s\n", conn->lasterrstr ); 88 | 89 | mongo_write_concern_destroy( write_concern ); 90 | bson_destroy( b ); 91 | mongo_destroy( conn ); 92 | 93 | return 0; 94 | } 95 | 96 | Notes 97 | ----- 98 | 99 | As you'll see in the code sample, the process for creating a write concern object 100 | is to initialize it, manually set any write concern values (e.g., ``w``, ``wtimeout`` 101 | for values of ``w`` greater than 1, ``j``, etc.), and then call ``mongo_write_concern_finish()`` 102 | on it. This will effectively create the equivalent ``getlasterror`` command. Note you must call 103 | ``mongo_write_concern_destroy()`` when you're finished with the write concern object. 104 | 105 | And for a longer example, see the 106 | `C driver's write concern tests `_. 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Notice:** Please note this repository has moved to https://github.com/EnterpriseDB/mongo_fdw 2 | 3 | MongoDB FDW for PostgreSQL 4 | ========================== 5 | 6 | This PostgreSQL extension implements a Foreign Data Wrapper (FDW) for 7 | [MongoDB][1]. For an example demonstrating this wrapper's use, see [our blog 8 | post][2]. Please also note that this version of `mongo_fdw` only works with 9 | PostgreSQL 9.2 or 9.3. 10 | 11 | 12 | Installation 13 | ------------ 14 | 15 | The MongoDB FDW includes the official MongoDB C Driver version 0.6. When you 16 | type `make`, the C driver's source code also gets automatically compiled and 17 | linked. 18 | 19 | To build on POSIX-compliant systems (like Linux and OS X), you need to ensure 20 | the `pg_config` executable is in your path when you run `make`. This executable 21 | is typically in your PostgreSQL installation's `bin` directory. For example: 22 | 23 | ```sh 24 | PATH=/usr/local/pgsql/bin/:$PATH make 25 | sudo PATH=/usr/local/pgsql/bin/:$PATH make install 26 | ``` 27 | 28 | Note that we have tested the `mongo_fdw` extension only on Fedora and Ubuntu 29 | systems. If you run into issues on other systems, please [let us know][3]. 30 | 31 | 32 | Usage 33 | ----- 34 | 35 | The following parameters can be set on a MongoDB foreign server object: 36 | 37 | * `address`: the address or hostname of the MongoDB server. 38 | Defaults to `127.0.0.1` 39 | * `port`: the port number of the MongoDB server. Defaults to `27017` 40 | 41 | The following parameters can be set on a MongoDB foreign table object: 42 | 43 | * `database`: the name of the MongoDB database to query. Defaults to `test` 44 | * `collection`: the name of the MongoDB collection to query. Defaults to 45 | the foreign table name used in the relevant `CREATE` command 46 | 47 | As an example, the following commands demonstrate loading the `mongo_fdw` 48 | wrapper, creating a server, and then creating a foreign table associated with 49 | a MongoDB collection. The commands also show specifying option values in the 50 | `OPTIONS` clause. If an option value isn't provided, the wrapper uses the 51 | default value mentioned above. 52 | 53 | `mongo_fdw` can collect data distribution statistics will incorporate them when 54 | estimating costs for the query execution plan. To see selected execution plans 55 | for a query, just run `EXPLAIN`. 56 | 57 | We also currently use the internal PostgreSQL `NAME` type to represent the BSON 58 | object identifier type (the `_id` field). 59 | 60 | ```sql 61 | -- load extension first time after install 62 | CREATE EXTENSION mongo_fdw; 63 | 64 | -- create server object 65 | CREATE SERVER mongo_server FOREIGN DATA WRAPPER mongo_fdw 66 | OPTIONS (address '127.0.0.1', port '27017'); 67 | 68 | -- create foreign table 69 | CREATE FOREIGN TABLE customer_reviews 70 | ( 71 | _id NAME, 72 | customer_id TEXT, 73 | review_date TIMESTAMP, 74 | review_rating INTEGER, 75 | product_id CHAR(10), 76 | product_title TEXT, 77 | product_group TEXT, 78 | product_category TEXT, 79 | similar_product_ids CHAR(10)[] 80 | ) 81 | SERVER mongo_server 82 | OPTIONS (database 'test', collection 'customer_reviews'); 83 | 84 | -- collect data distribution statistics 85 | ANALYZE customer_reviews; 86 | ``` 87 | 88 | 89 | Limitations 90 | ----------- 91 | 92 | * If the BSON document key contains uppercase letters or occurs within a 93 | nested document, `mongo_fdw` requires the corresponding column names to be 94 | declared in double quotes. For example, a nested field such as `"review": { 95 | "Votes": 19 }` should be declared as `"review.Votes" INTEGER` in the `CREATE 96 | TABLE` statement. 97 | 98 | * Note that PostgreSQL limits column names to 63 characters by default. If 99 | you need column names that are longer, you can increase the `NAMEDATALEN` 100 | constant in `src/include/pg_config_manual.h`, compile, and reinstall. 101 | 102 | 103 | Support 104 | ------- 105 | 106 | Please note this repository has moved to https://github.com/EnterpriseDB/mongo_fdw 107 | 108 | 109 | License 110 | ------- 111 | 112 | Copyright © 2012–2014 Citus Data, Inc. 113 | 114 | This program is free software: you can redistribute it and/or modify it under 115 | the terms of the GNU Lesser General Public License as published by the Free 116 | Software Foundation, either version 3 of the License, or (at your option) any 117 | later version. 118 | 119 | See the [`LICENSE`][5] file for full details. 120 | 121 | [1]: http://www.mongodb.com 122 | [2]: http://www.citusdata.com/blog/51-run-sql-on-mongodb 123 | [3]: https://github.com/citusdata/mongo_fdw/issues/new 124 | [5]: LICENSE 125 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source 10 | if NOT "%PAPER%" == "" ( 11 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 12 | ) 13 | 14 | if "%1" == "" goto help 15 | 16 | if "%1" == "help" ( 17 | :help 18 | echo.Please use `make ^` where ^ is one of 19 | echo. html to make standalone HTML files 20 | echo. dirhtml to make HTML files named index.html in directories 21 | echo. singlehtml to make a single large HTML file 22 | echo. pickle to make pickle files 23 | echo. json to make JSON files 24 | echo. htmlhelp to make HTML files and a HTML help project 25 | echo. qthelp to make HTML files and a qthelp project 26 | echo. devhelp to make HTML files and a Devhelp project 27 | echo. epub to make an epub 28 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 29 | echo. text to make text files 30 | echo. man to make manual pages 31 | echo. changes to make an overview over all changed/added/deprecated items 32 | echo. linkcheck to check all external links for integrity 33 | echo. doctest to run all doctests embedded in the documentation if enabled 34 | goto end 35 | ) 36 | 37 | if "%1" == "clean" ( 38 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 39 | del /q /s %BUILDDIR%\* 40 | goto end 41 | ) 42 | 43 | if "%1" == "html" ( 44 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 45 | echo. 46 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 47 | goto end 48 | ) 49 | 50 | if "%1" == "dirhtml" ( 51 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 52 | echo. 53 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 54 | goto end 55 | ) 56 | 57 | if "%1" == "singlehtml" ( 58 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 59 | echo. 60 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 61 | goto end 62 | ) 63 | 64 | if "%1" == "pickle" ( 65 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 66 | echo. 67 | echo.Build finished; now you can process the pickle files. 68 | goto end 69 | ) 70 | 71 | if "%1" == "json" ( 72 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 73 | echo. 74 | echo.Build finished; now you can process the JSON files. 75 | goto end 76 | ) 77 | 78 | if "%1" == "htmlhelp" ( 79 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 80 | echo. 81 | echo.Build finished; now you can run HTML Help Workshop with the ^ 82 | .hhp project file in %BUILDDIR%/htmlhelp. 83 | goto end 84 | ) 85 | 86 | if "%1" == "qthelp" ( 87 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 88 | echo. 89 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 90 | .qhcp project file in %BUILDDIR%/qthelp, like this: 91 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\MongoDBCDriver.qhcp 92 | echo.To view the help file: 93 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\MongoDBCDriver.ghc 94 | goto end 95 | ) 96 | 97 | if "%1" == "devhelp" ( 98 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 99 | echo. 100 | echo.Build finished. 101 | goto end 102 | ) 103 | 104 | if "%1" == "epub" ( 105 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 106 | echo. 107 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 108 | goto end 109 | ) 110 | 111 | if "%1" == "latex" ( 112 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 113 | echo. 114 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 115 | goto end 116 | ) 117 | 118 | if "%1" == "text" ( 119 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 120 | echo. 121 | echo.Build finished. The text files are in %BUILDDIR%/text. 122 | goto end 123 | ) 124 | 125 | if "%1" == "man" ( 126 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 127 | echo. 128 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 129 | goto end 130 | ) 131 | 132 | if "%1" == "changes" ( 133 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 134 | echo. 135 | echo.The overview file is in %BUILDDIR%/changes. 136 | goto end 137 | ) 138 | 139 | if "%1" == "linkcheck" ( 140 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 141 | echo. 142 | echo.Link check complete; look for any errors in the above output ^ 143 | or in %BUILDDIR%/linkcheck/output.txt. 144 | goto end 145 | ) 146 | 147 | if "%1" == "doctest" ( 148 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 149 | echo. 150 | echo.Testing of doctests in the sources finished, look at the ^ 151 | results in %BUILDDIR%/doctest/output.txt. 152 | goto end 153 | ) 154 | 155 | :end 156 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/src/env_standard.c: -------------------------------------------------------------------------------- 1 | /* env_standard.c */ 2 | 3 | /* Copyright 2009-2012 10gen Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* Vanilla networking designed to work on all systems. */ 19 | #include "env.h" 20 | #include 21 | #include 22 | 23 | #ifdef _WIN32 24 | #ifdef _MSC_VER 25 | #include // send,recv,socklen_t etc 26 | #include // addrinfo 27 | #else 28 | #include 29 | #include 30 | typedef int socklen_t; 31 | #endif 32 | #else 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #endif 42 | 43 | #ifndef NI_MAXSERV 44 | # define NI_MAXSERV 32 45 | #endif 46 | 47 | int mongo_env_close_socket( int socket ) { 48 | #ifdef _WIN32 49 | return closesocket( socket ); 50 | #else 51 | return close( socket ); 52 | #endif 53 | } 54 | 55 | int mongo_env_write_socket( mongo *conn, const void *buf, int len ) { 56 | const char *cbuf = buf; 57 | #ifdef _WIN32 58 | int flags = 0; 59 | #else 60 | #ifdef __APPLE__ 61 | int flags = 0; 62 | #else 63 | int flags = MSG_NOSIGNAL; 64 | #endif 65 | #endif 66 | 67 | while ( len ) { 68 | int sent = send( conn->sock, cbuf, len, flags ); 69 | if ( sent == -1 ) { 70 | if (errno == EPIPE) 71 | conn->connected = 0; 72 | conn->err = MONGO_IO_ERROR; 73 | return MONGO_ERROR; 74 | } 75 | cbuf += sent; 76 | len -= sent; 77 | } 78 | 79 | return MONGO_OK; 80 | } 81 | 82 | int mongo_env_read_socket( mongo *conn, void *buf, int len ) { 83 | char *cbuf = buf; 84 | while ( len ) { 85 | int sent = recv( conn->sock, cbuf, len, 0 ); 86 | if ( sent == 0 || sent == -1 ) { 87 | conn->err = MONGO_IO_ERROR; 88 | return MONGO_ERROR; 89 | } 90 | cbuf += sent; 91 | len -= sent; 92 | } 93 | 94 | return MONGO_OK; 95 | } 96 | 97 | /* This is a no-op in the generic implementation. */ 98 | int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) { 99 | return MONGO_OK; 100 | } 101 | 102 | int mongo_env_socket_connect( mongo *conn, const char *host, int port ) { 103 | struct sockaddr_in sa; 104 | socklen_t addressSize; 105 | int flag = 1; 106 | 107 | if ( ( conn->sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { 108 | conn->sock = 0; 109 | conn->err = MONGO_CONN_NO_SOCKET; 110 | return MONGO_ERROR; 111 | } 112 | 113 | memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) ); 114 | sa.sin_family = AF_INET; 115 | sa.sin_port = htons( port ); 116 | sa.sin_addr.s_addr = inet_addr( host ); 117 | addressSize = sizeof( sa ); 118 | 119 | if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) { 120 | mongo_env_close_socket( conn->sock ); 121 | conn->connected = 0; 122 | conn->sock = 0; 123 | conn->err = MONGO_CONN_FAIL; 124 | return MONGO_ERROR; 125 | } 126 | 127 | setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) ); 128 | 129 | if( conn->op_timeout_ms > 0 ) 130 | mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms ); 131 | 132 | conn->connected = 1; 133 | 134 | return MONGO_OK; 135 | } 136 | 137 | MONGO_EXPORT int mongo_env_sock_init( void ) { 138 | 139 | #if defined(_WIN32) 140 | WSADATA wsaData; 141 | WORD wVers; 142 | #elif defined(SIGPIPE) 143 | struct sigaction act; 144 | #endif 145 | 146 | static int called_once; 147 | static int retval; 148 | if (called_once) return retval; 149 | called_once = 1; 150 | 151 | #if defined(_WIN32) 152 | wVers = MAKEWORD(1, 1); 153 | retval = (WSAStartup(wVers, &wsaData) == 0); 154 | #elif defined(MACINTOSH) 155 | GUSISetup(GUSIwithInternetSockets); 156 | retval = 1; 157 | #elif defined(SIGPIPE) 158 | retval = 1; 159 | if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) < 0) 160 | retval = 0; 161 | else if (act.sa_handler == SIG_DFL) { 162 | act.sa_handler = SIG_IGN; 163 | if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) < 0) 164 | retval = 0; 165 | } 166 | #endif 167 | return retval; 168 | } 169 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/simple_test.c: -------------------------------------------------------------------------------- 1 | /* test.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include "env.h" 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | mongo conn[1]; 12 | mongo_cursor cursor[1]; 13 | bson b; 14 | int i; 15 | char hex_oid[25]; 16 | bson_timestamp_t ts = { 1, 2 }; 17 | 18 | const char *col = "c.simple"; 19 | const char *ns = "test.c.simple"; 20 | 21 | /* mongo_connect( conn, TEST_SERVER, 27017 ); */ 22 | 23 | /* Simple connect API 24 | mongo conn[1]; 25 | 26 | mongo_init( conn ); 27 | mongo_connect( conn, TEST_SERVER, 27017 ); 28 | mongo_destroy( conn ); 29 | 30 | * Advanced and replica set API 31 | mongo conn[1]; 32 | 33 | mongo_replset_init( conn, "foobar" ); 34 | mongo_set_connect_timeout( conn, 1000 ); 35 | mongo_replset_connect( conn ); 36 | mongo_destroy( conn ); 37 | 38 | * BSON API 39 | bson obj[1]; 40 | 41 | bson_init( obj ); 42 | bson_append_int( obj, "a", 1 ); 43 | bson_finish( obj ); 44 | mongo_insert( conn, obj ); 45 | bson_destroy( obj ); 46 | 47 | * BSON Iterator API 48 | bson_iterator i[1]; 49 | 50 | bson_iterator_init( i, b ); 51 | 52 | * Cursor API 53 | mongo_cursor cursor[1]; 54 | 55 | mongo_cursor_init( cursor, "test.ns" ); 56 | mongo_cursor_limit( cursor, 100 ); 57 | mongo_cursor_skip( cursor, 100 ); 58 | mongo_cursor_query( cursor, &query ); 59 | mongo_cursor_fields( cursor, &fields ); 60 | data = mongo_cursor_next( cursor ); 61 | mongo_cursor_destroy( cursor ); 62 | */ 63 | 64 | INIT_SOCKETS_FOR_WINDOWS; 65 | 66 | if( mongo_connect( conn , TEST_SERVER, 27017 ) != MONGO_OK ) { 67 | printf( "failed to connect\n" ); 68 | exit( 1 ); 69 | } 70 | 71 | mongo_cmd_drop_collection( conn, "test", col, NULL ); 72 | mongo_find_one( conn, ns, bson_empty( &b ), bson_empty( &b ), NULL ); 73 | 74 | for( i=0; i< 5; i++ ) { 75 | bson_init( &b ); 76 | 77 | bson_append_new_oid( &b, "_id" ); 78 | bson_append_timestamp( &b, "ts", &ts ); 79 | bson_append_double( &b , "a" , 17 ); 80 | bson_append_int( &b , "b" , 17 ); 81 | bson_append_string( &b , "c" , "17" ); 82 | 83 | { 84 | bson_append_start_object( &b , "d" ); 85 | bson_append_int( &b, "i", 71 ); 86 | bson_append_finish_object( &b ); 87 | } 88 | { 89 | bson_append_start_array( &b , "e" ); 90 | bson_append_int( &b, "0", 71 ); 91 | bson_append_string( &b, "1", "71" ); 92 | bson_append_finish_object( &b ); 93 | } 94 | 95 | bson_finish( &b ); 96 | ASSERT( mongo_insert( conn , ns , &b, NULL ) == MONGO_OK ); 97 | bson_destroy( &b ); 98 | } 99 | 100 | mongo_cursor_init( cursor, conn, ns ); 101 | 102 | while( mongo_cursor_next( cursor ) == MONGO_OK ) { 103 | bson_iterator it; 104 | bson_iterator_init( &it, mongo_cursor_bson( cursor ) ); 105 | while( bson_iterator_next( &it ) ) { 106 | fprintf( stderr, " %s: ", bson_iterator_key( &it ) ); 107 | 108 | switch( bson_iterator_type( &it ) ) { 109 | case BSON_DOUBLE: 110 | fprintf( stderr, "(double) %e\n", bson_iterator_double( &it ) ); 111 | break; 112 | case BSON_INT: 113 | fprintf( stderr, "(int) %d\n", bson_iterator_int( &it ) ); 114 | break; 115 | case BSON_STRING: 116 | fprintf( stderr, "(string) \"%s\"\n", bson_iterator_string( &it ) ); 117 | break; 118 | case BSON_OID: 119 | bson_oid_to_string( bson_iterator_oid( &it ), hex_oid ); 120 | fprintf( stderr, "(oid) \"%s\"\n", hex_oid ); 121 | break; 122 | case BSON_OBJECT: 123 | fprintf( stderr, "(subobject) {...}\n" ); 124 | break; 125 | case BSON_ARRAY: 126 | fprintf( stderr, "(array) [...]\n" ); 127 | break; 128 | case BSON_TIMESTAMP: 129 | fprintf( stderr, "(timestamp) [...]\n" ); 130 | break; 131 | default: 132 | fprintf( stderr, "(type %d)\n", bson_iterator_type( &it ) ); 133 | break; 134 | } 135 | } 136 | fprintf( stderr, "\n" ); 137 | } 138 | 139 | mongo_cursor_destroy( cursor ); 140 | ASSERT( mongo_cmd_drop_db( conn, "test" ) == MONGO_OK ); 141 | mongo_disconnect( conn ); 142 | 143 | ASSERT( mongo_check_connection( conn ) == MONGO_ERROR ); 144 | 145 | mongo_reconnect( conn ); 146 | 147 | ASSERT( mongo_check_connection( conn ) == MONGO_OK ); 148 | 149 | mongo_env_close_socket( conn->sock ); 150 | 151 | ASSERT( mongo_check_connection( conn ) == MONGO_ERROR ); 152 | 153 | mongo_reconnect( conn ); 154 | 155 | ASSERT( mongo_simple_int_command( conn, "admin", "ping", 1, NULL ) == MONGO_OK ); 156 | 157 | mongo_destroy( conn ); 158 | return 0; 159 | } 160 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 14 | 15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " singlehtml to make a single large HTML file" 22 | @echo " pickle to make pickle files" 23 | @echo " json to make JSON files" 24 | @echo " htmlhelp to make HTML files and a HTML help project" 25 | @echo " qthelp to make HTML files and a qthelp project" 26 | @echo " devhelp to make HTML files and a Devhelp project" 27 | @echo " epub to make an epub" 28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 29 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 30 | @echo " text to make text files" 31 | @echo " man to make manual pages" 32 | @echo " changes to make an overview of all changed/added/deprecated items" 33 | @echo " linkcheck to check all external links for integrity" 34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 35 | 36 | clean: 37 | -rm -rf $(BUILDDIR)/* 38 | 39 | html: 40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 41 | @echo 42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 43 | 44 | dirhtml: 45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 46 | @echo 47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 48 | 49 | singlehtml: 50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 51 | @echo 52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 53 | 54 | pickle: 55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 56 | @echo 57 | @echo "Build finished; now you can process the pickle files." 58 | 59 | json: 60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 61 | @echo 62 | @echo "Build finished; now you can process the JSON files." 63 | 64 | htmlhelp: 65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 66 | @echo 67 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 68 | ".hhp project file in $(BUILDDIR)/htmlhelp." 69 | 70 | qthelp: 71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 72 | @echo 73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MongoDBCDriver.qhcp" 76 | @echo "To view the help file:" 77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MongoDBCDriver.qhc" 78 | 79 | devhelp: 80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 81 | @echo 82 | @echo "Build finished." 83 | @echo "To view the help file:" 84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/MongoDBCDriver" 85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MongoDBCDriver" 86 | @echo "# devhelp" 87 | 88 | epub: 89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 90 | @echo 91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 92 | 93 | latex: 94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 95 | @echo 96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 98 | "(use \`make latexpdf' here to do that automatically)." 99 | 100 | latexpdf: 101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 102 | @echo "Running LaTeX files through pdflatex..." 103 | make -C $(BUILDDIR)/latex all-pdf 104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 105 | 106 | text: 107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 108 | @echo 109 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 110 | 111 | man: 112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 113 | @echo 114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 115 | 116 | changes: 117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 118 | @echo 119 | @echo "The overview file is in $(BUILDDIR)/changes." 120 | 121 | linkcheck: 122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 123 | @echo 124 | @echo "Link check complete; look for any errors in the above output " \ 125 | "or in $(BUILDDIR)/linkcheck/output.txt." 126 | 127 | doctest: 128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 129 | @echo "Testing of doctests in the sources finished, look at the " \ 130 | "results in $(BUILDDIR)/doctest/output.txt." 131 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/src/env_posix.c: -------------------------------------------------------------------------------- 1 | /* env_posix.c */ 2 | 3 | /* Copyright 2009-2012 10gen Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* Networking and other niceties for POSIX systems. */ 19 | #include "env.h" 20 | #include "mongo.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #ifndef NI_MAXSERV 34 | # define NI_MAXSERV 32 35 | #endif 36 | 37 | int mongo_env_close_socket( int socket ) { 38 | return close( socket ); 39 | } 40 | 41 | int mongo_env_sock_init( void ) { 42 | return 0; 43 | } 44 | 45 | int mongo_env_write_socket( mongo *conn, const void *buf, int len ) { 46 | const char *cbuf = buf; 47 | #ifdef __APPLE__ 48 | int flags = 0; 49 | #else 50 | int flags = MSG_NOSIGNAL; 51 | #endif 52 | 53 | while ( len ) { 54 | int sent = send( conn->sock, cbuf, len, flags ); 55 | if ( sent == -1 ) { 56 | if (errno == EPIPE) 57 | conn->connected = 0; 58 | __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno ); 59 | return MONGO_ERROR; 60 | } 61 | cbuf += sent; 62 | len -= sent; 63 | } 64 | 65 | return MONGO_OK; 66 | } 67 | 68 | int mongo_env_read_socket( mongo *conn, void *buf, int len ) { 69 | char *cbuf = buf; 70 | while ( len ) { 71 | int sent = recv( conn->sock, cbuf, len, 0 ); 72 | if ( sent == 0 || sent == -1 ) { 73 | __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno ); 74 | return MONGO_ERROR; 75 | } 76 | cbuf += sent; 77 | len -= sent; 78 | } 79 | 80 | return MONGO_OK; 81 | } 82 | 83 | int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) { 84 | struct timeval tv; 85 | tv.tv_sec = millis / 1000; 86 | tv.tv_usec = ( millis % 1000 ) * 1000; 87 | 88 | if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) ) == -1 ) { 89 | conn->err = MONGO_IO_ERROR; 90 | __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.", errno ); 91 | return MONGO_ERROR; 92 | } 93 | 94 | if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof( tv ) ) == -1 ) { 95 | __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.", errno ); 96 | return MONGO_ERROR; 97 | } 98 | 99 | return MONGO_OK; 100 | } 101 | 102 | int mongo_env_socket_connect( mongo *conn, const char *host, int port ) { 103 | char port_str[NI_MAXSERV]; 104 | int status; 105 | 106 | struct addrinfo ai_hints; 107 | struct addrinfo *ai_list = NULL; 108 | struct addrinfo *ai_ptr = NULL; 109 | 110 | conn->sock = 0; 111 | conn->connected = 0; 112 | sprintf(port_str,"%d",port); 113 | 114 | bson_sprintf( port_str, "%d", port ); 115 | 116 | memset( &ai_hints, 0, sizeof( ai_hints ) ); 117 | #ifdef AI_ADDRCONFIG 118 | ai_hints.ai_flags = AI_ADDRCONFIG; 119 | #endif 120 | ai_hints.ai_family = AF_UNSPEC; 121 | ai_hints.ai_socktype = SOCK_STREAM; 122 | 123 | status = getaddrinfo( host, port_str, &ai_hints, &ai_list ); 124 | if ( status != 0 ) { 125 | bson_errprintf( "getaddrinfo failed: %s", gai_strerror( status ) ); 126 | conn->err = MONGO_CONN_ADDR_FAIL; 127 | return MONGO_ERROR; 128 | } 129 | 130 | for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) { 131 | conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol ); 132 | if ( conn->sock < 0 ) { 133 | conn->sock = 0; 134 | continue; 135 | } 136 | 137 | status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen ); 138 | if ( status != 0 ) { 139 | mongo_env_close_socket( conn->sock ); 140 | conn->sock = 0; 141 | continue; 142 | } 143 | 144 | if ( ai_ptr->ai_protocol == IPPROTO_TCP ) { 145 | int flag = 1; 146 | 147 | setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, 148 | ( void * ) &flag, sizeof( flag ) ); 149 | if ( conn->op_timeout_ms > 0 ) 150 | mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms ); 151 | } 152 | 153 | conn->connected = 1; 154 | break; 155 | } 156 | 157 | freeaddrinfo( ai_list ); 158 | 159 | if ( ! conn->connected ) { 160 | conn->err = MONGO_CONN_FAIL; 161 | return MONGO_ERROR; 162 | } 163 | 164 | return MONGO_OK; 165 | } 166 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/source/connections.rst: -------------------------------------------------------------------------------- 1 | Connections 2 | ============================= 3 | 4 | All operations against a MongoDB server or cluster require a connection object. This document 5 | describes how to create and manage these connections. 6 | 7 | Basic connections 8 | ----------------- 9 | 10 | Use a basic connection to connect to a single MongoDB instances (``mongod``) or 11 | to the router for a shard cluster (``mongos``). 12 | 13 | .. code-block:: c 14 | 15 | mongo conn[1]; 16 | int result; 17 | 18 | result = mongo_connect( conn, "127.0.0.1", 27017 ); 19 | 20 | First we create the ``mongo`` object to manage the connection. Then we connect 21 | using ``mongo_connect``. If the function returns ``MONGO_OK``, then we've 22 | successfully connected. 23 | 24 | Notice that when specifying the host, we must use dot-decimal notation. If you'd like 25 | to use a hostname, then you'll have to compile the driver with the ``--use-platform=LINUX`` 26 | option and ensure that ``_MONGO_USE_GETADDRINFO`` is defined. 27 | 28 | In the event of an error, the result will be ``MONGO_ERROR``. You can then check the error 29 | value by examining the connection's ``err`` field. Continuing: 30 | 31 | .. code-block:: c 32 | 33 | if( result != MONGO_OK ) { 34 | switch( conn->err ) { 35 | case MONGO_CONN_NO_SOCKET: break; /**< Could not create a socket. */ 36 | case MONGO_CONN_FAIL: break; /**< An error occured while calling connect(). */ 37 | case MONGO_CONN_ADDR_FAIL: break; /**< An error occured while calling getaddrinfo(). */ 38 | case MONGO_CONN_NOT_MASTER: break; /**< Warning: connected to a non-master node (read-only). */ 39 | } 40 | 41 | These are the most likely error scenarios. For all possible errors, 42 | see the enum ``mongo_error_t``, and reference all constants beginning 43 | with ``MONGO_CONN``. 44 | 45 | Once you've finished with your connection object, be sure to pass it to 46 | ``mongo_destroy()``. This will close the socket and clean up any allocated 47 | memory: 48 | 49 | .. code-block:: c 50 | 51 | mongo_destroy( conn ); 52 | 53 | Replica set connections 54 | ----------------------- 55 | 56 | Use a replica set connection to connect to a replica set. 57 | 58 | The problem with connecting to a replica set is that you don't necessarily 59 | know which node is the primary node at connection time. This MongoDB C driver 60 | automatically figures out which node is the primary and then connects to it. 61 | 62 | To connection, you must provide: 63 | 64 | * The replica set's name 65 | 66 | And 67 | 68 | * At least one seed node. 69 | 70 | Here's how you go about that: 71 | 72 | .. code-block:: c 73 | 74 | mongo conn[1]; 75 | int result; 76 | 77 | mongo_replset_init( conn, "rs-dc-1" ); 78 | mongo_replset_add_seed( conn, '10.4.3.1', 27017 ); 79 | mongo_replset_add_seed( conn, '10.4.3.2', 27017 ); 80 | 81 | result = mongo_replset_connect( conn ); 82 | 83 | First we initiaize the connection object, providing the name of the replica set, 84 | in this case, "rs-dc-1." Next, we add two seed nodes. Finally, we connect 85 | by pass the connection to ``mongo_replset_connect``. 86 | 87 | As with the basic connection, we'll want to check for any errors on connect. Notice 88 | that there are two more error conditions we check for: 89 | 90 | .. code-block:: c 91 | 92 | if( result != MONGO_OK ) { 93 | switch( conn->err ) 94 | MONGO_CONN_NO_SOCKET: break; /**< Could not create a socket. */ 95 | MONGO_CONN_FAIL: break; /**< An error occured while calling connect(). */ 96 | MONGO_CONN_ADDR_FAIL: break; /**< An error occured while calling getaddrinfo(). */ 97 | MONGO_CONN_NOT_MASTER: break; /**< Warning: connected to a non-master node (read-only). */ 98 | MONGO_CONN_BAD_SET_NAME: break; /**< Given rs name doesn't match this replica set. */ 99 | MONGO_CONN_NO_PRIMARY: break; /**< Can't find primary in replica set. Connection closed. */ 100 | } 101 | 102 | When finished, be sure to destroy the connection object: 103 | 104 | .. code-block:: c 105 | 106 | mongo_destroy( conn ); 107 | 108 | Timeouts 109 | -------- 110 | 111 | You can set a timeout for read and write operation on the connection at any time: 112 | 113 | .. code-block:: c 114 | 115 | mongo_set_op_timeout( conn, 1000 ); 116 | 117 | This will set a 1000ms read-write timeout on the socket. If an operation fails, 118 | you'll see a generic MONGO_IO_ERROR on the connection's ``err`` field. Future 119 | versions of this driver will provide a more granular error code. 120 | 121 | Note this this will work only if you've compiled with driver with timeout support. 122 | 123 | I/O Errors and Reconnecting 124 | -------------------------- 125 | 126 | As you begin to use connection object to read and write data from MongoDB, 127 | you may ocassionally encounter a ``MONGO_IO_ERROR``. In most cases, 128 | you'll want to reconnect when you see this. Here's a very basic example: 129 | 130 | .. code-block:: c 131 | 132 | bson b[1]; 133 | 134 | bson_init( b ); 135 | bson_append_string( b, "hello", "world" ); 136 | bson_finish( b ); 137 | 138 | if( mongo_insert( conn, b ) == MONGO_ERROR && conn->err == MONGO_IO_ERROR ) 139 | mongo_reconnect( conn ); 140 | 141 | When reconnecting, you'll want to check the return value to ensure that the connection 142 | has succeeded. If you ever have any doubts about whether you're really connection, 143 | you can verify the health of the connection like so: 144 | 145 | .. code-block:: c 146 | 147 | mongo_check_connection( conn ); 148 | 149 | This function will return ``MONGO_OK`` if we're in fact connected. 150 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/cursors_test.c: -------------------------------------------------------------------------------- 1 | /* cursors.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void create_capped_collection( mongo *conn ) { 11 | bson b; 12 | 13 | bson_init( &b ); 14 | bson_append_string( &b, "create", "cursors" ); 15 | bson_append_bool( &b, "capped", 1 ); 16 | bson_append_int( &b, "size", 1000000 ); 17 | bson_finish( &b ); 18 | 19 | ASSERT( mongo_run_command( conn, "test", &b, NULL ) == MONGO_OK ); 20 | 21 | bson_destroy( &b ); 22 | } 23 | 24 | void insert_sample_data( mongo *conn, int n ) { 25 | bson b; 26 | int i; 27 | 28 | for( i=0; ierr == MONGO_CURSOR_EXHAUSTED ); 62 | 63 | mongo_cursor_destroy( cursor ); 64 | remove_sample_data( conn ); 65 | return 0; 66 | } 67 | 68 | int test_tailable( mongo *conn ) { 69 | mongo_cursor *cursor; 70 | bson b, e; 71 | int count; 72 | 73 | remove_sample_data( conn ); 74 | create_capped_collection( conn ); 75 | insert_sample_data( conn, 10000 ); 76 | 77 | bson_init( &b ); 78 | bson_append_start_object( &b, "$query" ); 79 | bson_append_finish_object( &b ); 80 | bson_append_start_object( &b, "$sort" ); 81 | bson_append_int( &b, "$natural", -1 ); 82 | bson_append_finish_object( &b ); 83 | bson_finish( &b ); 84 | 85 | cursor = mongo_find( conn, "test.cursors", &b, bson_empty( &e ), 0, 0, MONGO_TAILABLE ); 86 | bson_destroy( &b ); 87 | 88 | count = 0; 89 | while( mongo_cursor_next( cursor ) == MONGO_OK ) 90 | count++; 91 | 92 | ASSERT( count == 10000 ); 93 | 94 | ASSERT( mongo_cursor_next( cursor ) == MONGO_ERROR ); 95 | ASSERT( cursor->err == MONGO_CURSOR_PENDING ); 96 | 97 | insert_sample_data( conn, 10 ); 98 | 99 | count = 0; 100 | while( mongo_cursor_next( cursor ) == MONGO_OK ) { 101 | count++; 102 | } 103 | 104 | ASSERT( count == 10 ); 105 | 106 | ASSERT( mongo_cursor_next( cursor ) == MONGO_ERROR ); 107 | ASSERT( cursor->err == MONGO_CURSOR_PENDING ); 108 | 109 | mongo_cursor_destroy( cursor ); 110 | remove_sample_data( conn ); 111 | 112 | return 0; 113 | } 114 | 115 | int test_builder_api( mongo *conn ) { 116 | int count = 0; 117 | mongo_cursor cursor[1]; 118 | 119 | remove_sample_data( conn ); 120 | insert_sample_data( conn, 10000 ); 121 | mongo_cursor_init( cursor, conn, "test.cursors" ); 122 | 123 | while( mongo_cursor_next( cursor ) == MONGO_OK ) { 124 | count++; 125 | } 126 | ASSERT( count == 10000 ); 127 | 128 | mongo_cursor_destroy( cursor ); 129 | 130 | mongo_cursor_init( cursor, conn, "test.cursors" ); 131 | mongo_cursor_set_limit( cursor, 10 ); 132 | count = 0; 133 | while( mongo_cursor_next( cursor ) == MONGO_OK ) { 134 | count++; 135 | } 136 | ASSERT( count == 10 ); 137 | mongo_cursor_destroy( cursor ); 138 | 139 | return 0; 140 | } 141 | 142 | int test_bad_query( mongo *conn ) { 143 | mongo_cursor cursor[1]; 144 | bson b[1]; 145 | 146 | bson_init( b ); 147 | bson_append_start_object( b, "foo" ); 148 | bson_append_int( b, "$bad", 1 ); 149 | bson_append_finish_object( b ); 150 | bson_finish( b ); 151 | 152 | mongo_cursor_init( cursor, conn, "test.cursors" ); 153 | mongo_cursor_set_query( cursor, b ); 154 | 155 | ASSERT( mongo_cursor_next( cursor ) == MONGO_ERROR ); 156 | ASSERT( cursor->err == MONGO_CURSOR_QUERY_FAIL ); 157 | ASSERT( cursor->conn->lasterrcode == 10068 ); 158 | ASSERT( strlen( cursor->conn->lasterrstr ) > 0 ); 159 | 160 | mongo_cursor_destroy( cursor ); 161 | bson_destroy( b ); 162 | return 0; 163 | } 164 | 165 | int test_copy_cursor_data( mongo *conn ) { 166 | mongo_cursor cursor[1]; 167 | bson b[1]; 168 | 169 | insert_sample_data( conn, 10 ); 170 | mongo_cursor_init( cursor, conn, "test.cursors" ); 171 | 172 | mongo_cursor_next( cursor ); 173 | 174 | ASSERT( bson_copy( b, mongo_cursor_bson( cursor ) ) == MONGO_OK ); 175 | 176 | ASSERT( memcmp( (void *)b->data, (void *)(cursor->current).data, 177 | bson_size( &cursor->current ) ) == 0 ); 178 | 179 | mongo_cursor_destroy( cursor ); 180 | bson_destroy( b ); 181 | 182 | return 0; 183 | } 184 | 185 | int main() { 186 | 187 | mongo conn[1]; 188 | 189 | INIT_SOCKETS_FOR_WINDOWS; 190 | 191 | if( mongo_connect( conn, TEST_SERVER, 27017 ) != MONGO_OK ) { 192 | printf( "Failed to connect" ); 193 | exit( 1 ); 194 | } 195 | 196 | test_multiple_getmore( conn ); 197 | test_tailable( conn ); 198 | test_builder_api( conn ); 199 | test_bad_query( conn ); 200 | test_copy_cursor_data( conn ); 201 | 202 | mongo_destroy( conn ); 203 | return 0; 204 | } 205 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/src/env_win32.c: -------------------------------------------------------------------------------- 1 | /* env_win32.c */ 2 | 3 | /* Copyright 2009-2012 10gen Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* Networking and other niceties for WIN32. */ 19 | #include "env.h" 20 | #include "mongo.h" 21 | #include 22 | 23 | #ifdef _MSC_VER 24 | #include // send,recv,socklen_t etc 25 | #include // addrinfo 26 | #else 27 | #include // send,recv,socklen_t etc 28 | #include 29 | typedef int socklen_t; 30 | #endif 31 | 32 | #ifndef NI_MAXSERV 33 | # define NI_MAXSERV 32 34 | #endif 35 | 36 | int mongo_env_close_socket( int socket ) { 37 | return closesocket( socket ); 38 | } 39 | 40 | int mongo_env_write_socket( mongo *conn, const void *buf, int len ) { 41 | const char *cbuf = buf; 42 | int flags = 0; 43 | 44 | while ( len ) { 45 | int sent = send( conn->sock, cbuf, len, flags ); 46 | if ( sent == -1 ) { 47 | __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() ); 48 | conn->connected = 0; 49 | return MONGO_ERROR; 50 | } 51 | cbuf += sent; 52 | len -= sent; 53 | } 54 | 55 | return MONGO_OK; 56 | } 57 | 58 | int mongo_env_read_socket( mongo *conn, void *buf, int len ) { 59 | char *cbuf = buf; 60 | 61 | while ( len ) { 62 | int sent = recv( conn->sock, cbuf, len, 0 ); 63 | if ( sent == 0 || sent == -1 ) { 64 | __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() ); 65 | return MONGO_ERROR; 66 | } 67 | cbuf += sent; 68 | len -= sent; 69 | } 70 | 71 | return MONGO_OK; 72 | } 73 | 74 | int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) { 75 | if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&millis, 76 | sizeof( millis ) ) == -1 ) { 77 | __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.", 78 | WSAGetLastError() ); 79 | return MONGO_ERROR; 80 | } 81 | 82 | if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&millis, 83 | sizeof( millis ) ) == -1 ) { 84 | __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.", 85 | WSAGetLastError() ); 86 | return MONGO_ERROR; 87 | } 88 | 89 | return MONGO_OK; 90 | } 91 | 92 | int mongo_env_socket_connect( mongo *conn, const char *host, int port ) { 93 | char port_str[NI_MAXSERV]; 94 | char errstr[MONGO_ERR_LEN]; 95 | int status; 96 | 97 | struct addrinfo ai_hints; 98 | struct addrinfo *ai_list = NULL; 99 | struct addrinfo *ai_ptr = NULL; 100 | 101 | conn->sock = 0; 102 | conn->connected = 0; 103 | 104 | bson_sprintf( port_str, "%d", port ); 105 | 106 | memset( &ai_hints, 0, sizeof( ai_hints ) ); 107 | ai_hints.ai_family = AF_UNSPEC; 108 | ai_hints.ai_socktype = SOCK_STREAM; 109 | ai_hints.ai_protocol = IPPROTO_TCP; 110 | 111 | status = getaddrinfo( host, port_str, &ai_hints, &ai_list ); 112 | if ( status != 0 ) { 113 | bson_sprintf( errstr, "getaddrinfo failed with error %d", status ); 114 | __mongo_set_error( conn, MONGO_CONN_ADDR_FAIL, errstr, WSAGetLastError() ); 115 | return MONGO_ERROR; 116 | } 117 | 118 | for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) { 119 | conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype, 120 | ai_ptr->ai_protocol ); 121 | 122 | if ( conn->sock < 0 ) { 123 | __mongo_set_error( conn, MONGO_SOCKET_ERROR, "socket() failed", 124 | WSAGetLastError() ); 125 | conn->sock = 0; 126 | continue; 127 | } 128 | 129 | status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen ); 130 | if ( status != 0 ) { 131 | __mongo_set_error( conn, MONGO_SOCKET_ERROR, "connect() failed", 132 | WSAGetLastError() ); 133 | mongo_env_close_socket( conn->sock ); 134 | conn->sock = 0; 135 | continue; 136 | } 137 | 138 | if ( ai_ptr->ai_protocol == IPPROTO_TCP ) { 139 | int flag = 1; 140 | 141 | setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, 142 | ( void * ) &flag, sizeof( flag ) ); 143 | 144 | if ( conn->op_timeout_ms > 0 ) 145 | mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms ); 146 | } 147 | 148 | conn->connected = 1; 149 | break; 150 | } 151 | 152 | freeaddrinfo( ai_list ); 153 | 154 | if ( ! conn->connected ) { 155 | conn->err = MONGO_CONN_FAIL; 156 | return MONGO_ERROR; 157 | } 158 | else { 159 | mongo_clear_errors( conn ); 160 | return MONGO_OK; 161 | } 162 | } 163 | 164 | MONGO_EXPORT int mongo_env_sock_init( void ) { 165 | 166 | WSADATA wsaData; 167 | WORD wVers; 168 | static int called_once; 169 | static int retval; 170 | 171 | if (called_once) return retval; 172 | 173 | called_once = 1; 174 | wVers = MAKEWORD(1, 1); 175 | retval = (WSAStartup(wVers, &wsaData) == 0); 176 | 177 | return retval; 178 | } 179 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/json_test.c: -------------------------------------------------------------------------------- 1 | /* testjson.c */ 2 | 3 | #include "test.h" 4 | #include 5 | #include 6 | 7 | #include "mongo.h" 8 | #include "json/json.h" 9 | #include "md5.h" 10 | 11 | void json_to_bson_append_element( bson_buffer *bb , const char *k , struct json_object *v ); 12 | 13 | /** 14 | should already have called start_array 15 | this will not call start/finish 16 | */ 17 | void json_to_bson_append_array( bson_buffer *bb , struct json_object *a ) { 18 | int i; 19 | char buf[10]; 20 | for ( i=0; i 4, this returns 0. The Unicode 68 | * definition of UTF-8 goes up to 4-byte sequences. 69 | */ 70 | static int isLegalUTF8( const unsigned char *source, int length ) { 71 | unsigned char a; 72 | const unsigned char *srcptr = source + length; 73 | switch ( length ) { 74 | default: 75 | return 0; 76 | /* Everything else falls through when "true"... */ 77 | case 4: 78 | if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0; 79 | case 3: 80 | if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0; 81 | case 2: 82 | if ( ( a = ( *--srcptr ) ) > 0xBF ) return 0; 83 | switch ( *source ) { 84 | /* no fall-through in this inner switch */ 85 | case 0xE0: 86 | if ( a < 0xA0 ) return 0; 87 | break; 88 | case 0xF0: 89 | if ( a < 0x90 ) return 0; 90 | break; 91 | case 0xF4: 92 | if ( a > 0x8F ) return 0; 93 | break; 94 | default: 95 | if ( a < 0x80 ) return 0; 96 | } 97 | case 1: 98 | if ( *source >= 0x80 && *source < 0xC2 ) return 0; 99 | if ( *source > 0xF4 ) return 0; 100 | } 101 | return 1; 102 | } 103 | 104 | /* If the name is part of a db ref ($ref, $db, or $id), then return true. */ 105 | static int bson_string_is_db_ref( const unsigned char *string, const int length ) { 106 | int result = 0; 107 | 108 | if( length >= 4 ) { 109 | if( string[1] == 'r' && string[2] == 'e' && string[3] == 'f' ) 110 | result = 1; 111 | } 112 | else if( length >= 3 ) { 113 | if( string[1] == 'i' && string[2] == 'd' ) 114 | result = 1; 115 | else if( string[1] == 'd' && string[2] == 'b' ) 116 | result = 1; 117 | } 118 | 119 | return result; 120 | } 121 | 122 | static int bson_validate_string( bson *b, const unsigned char *string, 123 | const int length, const char check_utf8, const char check_dot, 124 | const char check_dollar ) { 125 | 126 | int position = 0; 127 | int sequence_length = 1; 128 | 129 | if( check_dollar && string[0] == '$' ) { 130 | if( !bson_string_is_db_ref( string, length ) ) 131 | b->err |= BSON_FIELD_INIT_DOLLAR; 132 | } 133 | 134 | while ( position < length ) { 135 | if ( check_dot && *( string + position ) == '.' ) { 136 | b->err |= BSON_FIELD_HAS_DOT; 137 | } 138 | 139 | if ( check_utf8 ) { 140 | sequence_length = trailingBytesForUTF8[*( string + position )] + 1; 141 | if ( ( position + sequence_length ) > length ) { 142 | b->err |= BSON_NOT_UTF8; 143 | return BSON_ERROR; 144 | } 145 | if ( !isLegalUTF8( string + position, sequence_length ) ) { 146 | b->err |= BSON_NOT_UTF8; 147 | return BSON_ERROR; 148 | } 149 | } 150 | position += sequence_length; 151 | } 152 | 153 | return BSON_OK; 154 | } 155 | 156 | 157 | int bson_check_string( bson *b, const char *string, 158 | const int length ) { 159 | 160 | return bson_validate_string( b, ( const unsigned char * )string, length, 1, 0, 0 ); 161 | } 162 | 163 | int bson_check_field_name( bson *b, const char *string, 164 | const int length ) { 165 | 166 | return bson_validate_string( b, ( const unsigned char * )string, length, 1, 1, 1 ); 167 | } 168 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/source/building.rst: -------------------------------------------------------------------------------- 1 | Building the MongoDB C Driver 2 | ============================= 3 | 4 | First checkout the version you want to build. *Always build from a particular tag, since HEAD may be 5 | a work in progress.* For example, to build version 0.5.1, run: 6 | 7 | .. code-block:: bash 8 | 9 | git checkout v0.5.1 10 | 11 | Then follow the build steps below. 12 | 13 | Compile options with custom defines 14 | ---------------------------------- 15 | 16 | Before compiling, you should note the following compile options. 17 | 18 | For big-endian support, define: 19 | 20 | - ``MONGO_BIG_ENDIAN`` 21 | 22 | If your compiler has a plain ``bool`` type, define: 23 | 24 | - ``MONGO_HAVE_BOOL`` 25 | 26 | Alternatively, if you must include ``stdbool.h`` to get ``bool``, define: 27 | 28 | - ``MONGO_HAVE_STDBOOL`` 29 | 30 | If you're not using C99, then you must choose your 64-bit integer type by 31 | defining one of these: 32 | 33 | - ``MONGO_HAVE_STDINT`` - Define this if you have ```` for int64_t. 34 | - ``MONGO_HAVE_UNISTD`` - Define this if you have ```` for int64_t. 35 | - ``MONGO_USE__INT64`` - Define this if ``__int64`` is your compiler's 64bit type (MSVC). 36 | - ``MONGO_USE_LONG_LONG_INT`` - Define this if ``long long int`` is your compiler's 64-bit type. 37 | 38 | Building with Make: 39 | ------------------- 40 | 41 | If you're building the driver on posix-compliant platforms, including on OS X 42 | and Linux, then you can build with ``make``. 43 | 44 | To compile the driver, run: 45 | 46 | .. code-block:: bash 47 | 48 | make 49 | 50 | This will build the following libraries: 51 | 52 | * libbson.a 53 | * libbson.so (libbson.dylib) 54 | * libmongoc.a 55 | * lobmongoc.so (libmongoc.dylib) 56 | 57 | You can install the libraries with make as well: 58 | 59 | .. code-block:: bash 60 | 61 | make install 62 | 63 | And you can run the tests: 64 | 65 | .. code-block:: bash 66 | 67 | make test 68 | 69 | You can even build the docs: 70 | 71 | .. code-block:: bash 72 | 73 | make docs 74 | 75 | By default, ``make`` will build the project in ``c99`` mode. If you want to change the 76 | language standard, set the value of STD. For example, if you want to build using 77 | the ANSI C standard, set STD to c89: 78 | 79 | .. code-block:: bash 80 | 81 | make STD=c89 82 | 83 | Once you've built and installed the libraries, you can compile the sample 84 | with ``gcc`` like so: 85 | 86 | .. code-block:: bash 87 | 88 | gcc --std=c99 -I/usr/local/include -L/usr/local/lib -o example docs/examples/example.c -lmongoc 89 | 90 | If you want to statically link the program, add the ``-static`` option: 91 | 92 | .. code-block:: bash 93 | 94 | gcc --std=c99 -static -I/usr/local/include -L/usr/local/lib -o example docs/examples/example.c -lmongoc 95 | 96 | Then run the program: 97 | 98 | .. code-block:: bash 99 | 100 | ./example 101 | 102 | Building with SCons: 103 | -------------------- 104 | 105 | You may also build the driver using the Python build utility, SCons_. 106 | This is required if you're building on Windows. Make sure you've 107 | installed SCons, and then from the project root, enter: 108 | 109 | .. _SCons: http://www.scons.org/ 110 | 111 | .. code-block:: bash 112 | 113 | scons 114 | 115 | This will build static and dynamic libraries for both ``BSON`` and for the 116 | the driver as a complete package. It's recommended that you build in C99 mode 117 | with optimizations enabled: 118 | 119 | .. code-block:: bash 120 | 121 | scons --c99 122 | 123 | Once you've built the libraries, you can compile a program with ``gcc`` like so: 124 | 125 | .. code-block:: bash 126 | 127 | gcc --std=c99 -static -Isrc -o example docs/example/example.c libmongoc.a 128 | 129 | On Posix systems, you may also install the libraries with scons: 130 | 131 | .. code-block:: bash 132 | 133 | scons install 134 | 135 | To build the docs: 136 | 137 | .. code-block:: bash 138 | 139 | scons docs 140 | 141 | Building on Windows 142 | ------------------- 143 | 144 | When building the driver on Windows, you must use the Python build 145 | utility, SCons_. For your compiler, we recommend that you use Visual Studio. 146 | If you don't have Visual Studio, a free version is available. Search for Visual 147 | Studio C++ Express to find it. 148 | 149 | If you're running on 32-bit Windows, you must compile the driver in 32-bit mode: 150 | 151 | .. code-block:: bash 152 | 153 | scons --m32 154 | 155 | If getaddrinfo and friends aren't available on your version of Windows, you may 156 | compile without these features like so: 157 | 158 | .. code-block:: bash 159 | 160 | scons --m32 --standard-env 161 | 162 | Platform-specific features 163 | -------------------------- 164 | 165 | The original goal of the MongoDB C driver was to provide a very basic library 166 | capable of being embedded anywhere. This goal is now evolving somewhat given 167 | the increased use of the driver. In particular, it now makes sense to provide 168 | platform-specific features, such as socket timeouts and DNS resolution, and to 169 | return platform-specific error codes. 170 | 171 | To that end, we've organized all platform-specific code in the following files: 172 | 173 | * ``env_standard.c``: a standard, platform-agnostic implementation. 174 | * ``env_posix.c``: an implementation geared for Posix-compliant systems (Linux, OS X). 175 | * ``env_win32.c``: a Windows implementation. 176 | 177 | Each of these implements the interface defined in ``env.h``. 178 | 179 | When building with ``make``, we use ``env_posix.c``. When building with SCons_, we 180 | use ``env_posix.c`` or ``env_win32.c``, depending on the platform. 181 | 182 | If you want to compile with the generic, platform implementation, you have to do so 183 | explicity. In SCons_: 184 | 185 | .. code-block:: bash 186 | 187 | scons --standard-env 188 | 189 | Using ``make``: 190 | 191 | .. code-block:: bash 192 | 193 | make ENV=standard 194 | 195 | Dependencies 196 | ------------ 197 | 198 | The driver itself has no dependencies, but one of the tests shows how to create a JSON-to-BSON 199 | converter. For that test to run, you'll need JSON-C_. 200 | 201 | .. _JSON-C: http://oss.metaparadigm.com/json-c/ 202 | 203 | Test suite 204 | ---------- 205 | 206 | Make sure that you're running mongod on 127.0.0.1 on the default port (27017). The replica set 207 | test assumes a replica set with at least three nodes running at 127.0.0.1 and starting at port 208 | 30000. Note that the driver does not recognize 'localhost' as a valid host name. 209 | 210 | With make: 211 | 212 | .. code-block:: bash 213 | 214 | make test 215 | 216 | To compile and run the tests with SCons: 217 | 218 | .. code-block:: bash 219 | 220 | scons test 221 | 222 | You may optionally specify a remote server: 223 | 224 | .. code-block:: bash 225 | 226 | scons test --test-server=123.4.5.67 227 | 228 | You may also specify an alternate starting port for the replica set members: 229 | 230 | .. code-block:: bash 231 | 232 | scons test --test-server=123.4.5.67 --seed-start-port=40000 233 | 234 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/source/bson.rst: -------------------------------------------------------------------------------- 1 | BSON 2 | ============================= 3 | 4 | BSON (i.e., binary structured object notation) is the binary format used 5 | by MongoDB to store data and express queries and commands. To work with 6 | MongoDB is to trade in BSON objects. This document describes how to 7 | create, read, and destroy BSON objects using the MongoDB C Driver. 8 | 9 | Libraries 10 | --------- 11 | 12 | A brief note on libraries. 13 | 14 | When you compile the driver, the BSON library is included in the 15 | driver. This means that when you include ``mongo.h``, you have access 16 | to all the functions declared in ``bson.h``. 17 | 18 | If you want to use BSON independently, you don't need ``libmongoc``: when you compile 19 | the driver, you'll also get shared and static libraries for ``libbson``. You 20 | can link to this library and simple require ``bson.h``. 21 | 22 | Using BSON objects 23 | ------------------ 24 | 25 | The pattern of BSON object usage is pretty simple. Here are the steps: 26 | 27 | 1. Initiate a new BSON object. 28 | 2. Construct the object using the bson_append_* methods. 29 | 3. Pass the object to bson_finish() to finalize it. The object is now ready to use. 30 | 4. When you're done with it, pass the object to bson_destroy() to free up any allocated 31 | memory. 32 | 33 | To demonstrate, let's create a BSON object corresponding to the simple JSON object 34 | ``{count: 1001}``. 35 | 36 | .. code-block:: c 37 | 38 | bson b[1]; 39 | 40 | bson_init( b ); 41 | bson_append_int( b, "count", 1001 ); 42 | bson_finish( b ); 43 | 44 | // BSON object now ready for use 45 | 46 | bson_destroy( b ); 47 | 48 | That's all there is to creating a basic object. 49 | 50 | Creating complex BSON objects 51 | _____________________________ 52 | 53 | BSON objects can contain arrays as well as sub-objects. Here 54 | we'll see how to create these by building the bson object 55 | corresponding to the following JSON object: 56 | 57 | .. code-block:: javascript 58 | 59 | { 60 | name: "Kyle", 61 | 62 | colors: [ "red", "blue", "green" ], 63 | 64 | address: { 65 | city: "New York", 66 | zip: "10011-4567" 67 | } 68 | } 69 | 70 | .. code-block:: c 71 | 72 | bson b[1]; 73 | 74 | bson_init( b ); 75 | bson_append_string( b, "name", "Kyle" ); 76 | 77 | bson_append_start_array( b, "colors" ); 78 | bson_append_string( b, "0", "red" ); 79 | bson_append_string( b, "1", "blue" ); 80 | bson_append_string( b, "2", "green" ); 81 | bson_append_finish_array( b ); 82 | 83 | bson_append_start_object( b, "address" ); 84 | bson_append_string( b, "city", "New York" ); 85 | bson_append_string( b, "zip", "10011-4567" ); 86 | bson_append_finish_object( b ); 87 | 88 | if( bson_finish( b ) != BSON_OK ) 89 | printf(" Error. "); 90 | 91 | Notice that for the array, we have to manually set the index values 92 | from "0" to *n*, where *n* is the number of elements in the array. 93 | 94 | You'll notice that some knowledge of the BSON specification and 95 | of the available types is necessary. For that, take a few minutes to 96 | consult the `official BSON specification `_. 97 | 98 | Error handling 99 | -------------- 100 | 101 | The names of BSON object values, as well as all strings, must be 102 | encoded as valid UTF-8. The BSON library will automatically check 103 | the encoding of strings as you create BSON objects, and if the objects 104 | are invalid, you'll be able to check for this condition. All of the 105 | bson_append_* methods will return either BSON_OK for BSON_ERROR. You 106 | can check in your code for the BSON_ERROR condition and then see the 107 | exact nature of the error by examining the bson->err field. This bitfield 108 | can contain any of the following values: 109 | 110 | * BSON_VALID 111 | * BSON_NOT_UTF8 112 | * BSON_FIELD_HAS_DOT 113 | * BSON_FIELD_INIT_DOLLAR 114 | * BSON_ALREADY_FINISHED 115 | 116 | The most important of these is ``BSON_NOT_UTF8`` because the BSON 117 | objects cannot be used with MongoDB if they're not valid UTF8. 118 | 119 | To keep your code clean, you may want to check for BSON_OK only when 120 | calling ``bson_finish()``. If the object is not valid, it will not be 121 | finished, so it's quite important to check the return code here. 122 | 123 | Reading BSON objects 124 | -------------------- 125 | 126 | You can read through a BSON object using a ``bson_iterator``. For 127 | a complete example, you may want to read through the implementation 128 | of ``bson_print_raw()`` (in ``bson.h``). But the basic idea is to 129 | initialize a ``bson_iterator`` object and then iterate over each 130 | successive element using ``bson_iterator_next()``. Let's take an 131 | example. Suppose we have a finished object of type ``bson*`` called ``b``: 132 | 133 | .. code-block:: c 134 | 135 | 136 | bson_iterator i[1]; 137 | bson_type type; 138 | const char * key; 139 | 140 | bson_iterator_init( i, b ); 141 | 142 | type = bson_iterator_next( i ); 143 | key = bson_iterator_key( i ); 144 | 145 | printf( "Type: %d, Key: %s\n", type, key ); 146 | 147 | We've advanced to the first element in the object, and we can print 148 | both it's BSON numeric type and its key name. To print the value, 149 | we need to use the type to find the correct method for reading the 150 | value. For instance, if the element is a string, then we use 151 | ``bson_iterator_string`` to return the result: 152 | 153 | .. code-block:: c 154 | 155 | printf( "Value: %s\n", bson_iterator_string( i ) ); 156 | 157 | In addition to iterating over each successive BSON element, 158 | we can use the ``bson_find()`` function to jump directly 159 | to an element by name. Again, suppose that ``b`` is a pointer 160 | to a ``bson`` object. If we want to jump to the element 161 | named "address", we use ``bson_find()`` like so: 162 | 163 | .. code-block:: c 164 | 165 | bson_iterator i[1], sub[i]; 166 | bson_type type; 167 | 168 | type = bson_find( i, b, "address" ); 169 | 170 | This will initialize the iterator, ``i``, and position 171 | it at the element named "address". The return value 172 | will be the "address" element's type. 173 | 174 | Reading sub-objects and arrays 175 | ------------------------------ 176 | 177 | Since "address" is a sub-object, we need to specially 178 | iterate it. To do that, we get the raw value and initialize 179 | a new BSON iterator like so: 180 | 181 | .. code-block:: c 182 | 183 | type = bson_find( i, b, "address" ); 184 | 185 | bson_iterator_subiterator( i, sub ); 186 | 187 | The function ``bson_iterator_subiterator`` initializes 188 | the iterator ``sub`` and points it to the beginning of the 189 | sub-object. From there, we can iterate over 190 | ``sub`` until we reach ``BSON_EOO``, indicating the end of the 191 | sub-object. 192 | 193 | If you want to work with a sub-object by itself, there's 194 | a function, ``bson_iterator_subobject``, for initializing 195 | a new ``bson`` object with the value of the sub-object. Note 196 | that this does not copy the object. If you want a copy of the 197 | object, use ``bsop_copy()``. 198 | 199 | .. code-block:: c 200 | 201 | bson copy[1]; 202 | 203 | bson_copy( copy, sub ); 204 | 205 | Getting a Raw BSON Pointer 206 | -------------------------- 207 | 208 | Sometimes you'll want to access the ``char *`` that 209 | points to the buffer storing the raw BSON object. For that, 210 | use the ``bson_data()`` function. You can use this in concert 211 | with the bson_iterator_from_buffer() function to initialize an 212 | iterator: 213 | 214 | .. code-block:: c 215 | 216 | bson_iterator i[1]; 217 | 218 | bson_iterator_from_buffer( i, bson_data( b ) ); 219 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/Makefile: -------------------------------------------------------------------------------- 1 | # MongoDB C Driver Makefile 2 | # 3 | # Copyright 2009, 2010 10gen Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Version 18 | MONGO_MAJOR=0 19 | MONGO_MINOR=6 20 | MONGO_PATCH=0 21 | BSON_MAJOR=$(MONGO_MAJOR) 22 | BSON_MINOR=$(MONGO_MINOR) 23 | BSON_PATCH=$(MONGO_PATCH) 24 | 25 | # Library names 26 | MONGO_LIBNAME=libmongoc 27 | BSON_LIBNAME=libbson 28 | 29 | # Standard or posix env. 30 | ENV?=posix 31 | 32 | # TODO: add replica set test, cpp test, platform tests, json_test 33 | TESTS=test/auth_test test/bson_test test/bson_subobject_test test/count_delete_test \ 34 | test/cursors_test test/endian_swap_test test/errors_test test/examples_test \ 35 | test/functions_test test/gridfs_test test/helpers_test \ 36 | test/oid_test test/resize_test test/simple_test test/sizes_test test/update_test \ 37 | test/validate_test test/write_concern_test test/commands_test 38 | MONGO_OBJECTS=src/bson.o src/encoding.o src/gridfs.o src/md5.o src/mongo.o \ 39 | src/numbers.o 40 | BSON_OBJECTS=src/bson.o src/numbers.o src/encoding.o 41 | 42 | ifeq ($(ENV),posix) 43 | TESTS+=test/env_posix_test 44 | MONGO_OBJECTS+=src/env_posix.o 45 | else 46 | MONGO_OBJECTS+=src/env_standard.o 47 | endif 48 | 49 | DYN_MONGO_OBJECTS=$(foreach i,$(MONGO_OBJECTS),$(patsubst %.o,%.os,$(i))) 50 | DYN_BSON_OBJECTS=$(foreach i,$(BSON_OBJECTS),$(patsubst %.o,%.os,$(i))) 51 | 52 | # Compile flags 53 | ALL_DEFINES=$(DEFINES) 54 | ALL_DEFINES+=-D_POSIX_SOURCE 55 | CC:=$(shell sh -c 'type $(CC) >/dev/null 2>/dev/null && echo $(CC) || echo gcc') 56 | DYN_FLAGS:=-fPIC -DMONGO_DLL_BUILD 57 | 58 | # Endianness check 59 | endian := $(shell sh -c 'echo "ab" | od -x | grep "6261" >/dev/null && echo little || echo big') 60 | ifeq ($(endian),big) 61 | ALL_DEFINES+=-DMONGO_BIG_ENDIAN 62 | endif 63 | 64 | # Int64 type check 65 | int64:=$(shell ./check_int64.sh $(CC) stdint.h && echo stdint) 66 | ifeq ($(int64),stdint) 67 | ALL_DEFINES+=-DMONGO_HAVE_STDINT 68 | else 69 | int64:=$(shell ./check_int64.sh $(CC) unistd.h && echo unistd) 70 | ifeq ($(int64),unistd) 71 | ALL_DEFINES+=-DMONGO_HAVE_UNISTD 72 | endif 73 | endif 74 | $(shell rm header_check.tmp tmp.c) 75 | 76 | TEST_DEFINES=$(ALL_DEFINES) 77 | TEST_DEFINES+=-DTEST_SERVER="\"127.0.0.1\"" 78 | 79 | OPTIMIZATION?=-O3 80 | WARNINGS?=-Wall 81 | DEBUG?=-ggdb 82 | STD?=c99 83 | PEDANTIC?=-pedantic 84 | ALL_CFLAGS=-std=$(STD) $(PEDANTIC) $(CFLAGS) $(OPTIMIZATION) $(WARNINGS) $(DEBUG) $(ALL_DEFINES) 85 | ALL_LDFLAGS=$(LDFLAGS) 86 | 87 | # Shared libraries 88 | DYLIBSUFFIX=so 89 | STLIBSUFFIX=a 90 | 91 | MONGO_DYLIBNAME=$(MONGO_LIBNAME).$(DYLIBSUFFIX) 92 | MONGO_DYLIB_MAJOR_NAME=$(MONGO_DYLIBNAME).$(MONGO_MAJOR) 93 | MONGO_DYLIB_MINOR_NAME=$(MONGO_DYLIB_MAJOR_NAME).$(MONGO_MINOR) 94 | MONGO_DYLIB_PATCH_NAME=$(MONGO_DYLIB_MINOR_NAME).$(MONGO_PATCH) 95 | MONGO_DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(MONGO_DYLIB_MINOR_NAME) -o $(MONGO_DYLIBNAME) $(ALL_LDFLAGS) $(DYN_MONGO_OBJECTS) 96 | 97 | BSON_DYLIBNAME=$(BSON_LIBNAME).$(DYLIBSUFFIX) 98 | BSON_DYLIB_MAJOR_NAME=$(BSON_DYLIBNAME).$(BSON_MAJOR) 99 | BSON_DYLIB_MINOR_NAME=$(BSON_DYLIB_MAJOR_NAME).$(BSON_MINOR) 100 | BSON_DYLIB_PATCH_NAME=$(BSON_DYLIB_MINOR_NAME).$(BSON_PATCH) 101 | BSON_DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(BSON_DYLIB_MINOR_NAME) -o $(BSON_DYLIBNAME) $(ALL_LDFLAGS) $(DYN_BSON_OBJECTS) 102 | 103 | # Static libraries 104 | MONGO_STLIBNAME=$(MONGO_LIBNAME).$(STLIBSUFFIX) 105 | BSON_STLIBNAME=$(BSON_LIBNAME).$(STLIBSUFFIX) 106 | 107 | # Overrides 108 | kernel_name := $(shell sh -c 'uname -s 2>/dev/null || echo not') 109 | ifeq ($(kernel_name),SunOS) 110 | ALL_LDFLAGS+=-ldl -lnsl -lsocket 111 | INSTALL_CMD=cp -r 112 | MONGO_DYLIB_MAKE_CMD=$(CC) -G -o $(MONGO_DYLIBNAME) -h $(MONGO_DYLIB_MINOR_NAME) $(ALL_LDFLAGS) 113 | BSON_DYLIB_MAKE_CMD=$(CC) -G -o $(BSON_DYLIBNAME) -h $(BSON_DYLIB_MINOR_NAME) $(ALL_LDFLAGS) 114 | endif 115 | ifeq ($(kernel_name),Darwin) 116 | ALL_CFLAGS+=-std=$(STD) $(CFLAGS) $(OPTIMIZATION) $(WARNINGS) $(DEBUG) $(ALL_DEFINES) 117 | DYLIBSUFFIX=dylib 118 | MONGO_DYLIB_MINOR_NAME=$(MONGO_LIBNAME).$(DYLIBSUFFIX).$(MONGO_MAJOR).$(MONGO_MINOR) 119 | MONGO_DYLIB_MAJOR_NAME=$(MONGO_LIBNAME).$(DYLIBSUFFIX).$(MONGO_MAJOR) 120 | MONGO_DYLIB_MAKE_CMD=$(CC) -shared -Wl,-install_name,$(MONGO_DYLIB_MINOR_NAME) -o $(MONGO_DYLIBNAME) 121 | 122 | BSON_DYLIB_MINOR_NAME=$(BSON_LIBNAME).$(DYLIBSUFFIX).$(BSON_MAJOR).$(BSON_MINOR) 123 | BSON_DYLIB_MAJOR_NAME=$(BSON_LIBNAME).$(DYLIBSUFFIX).$(BSON_MAJOR) 124 | BSON_DYLIB_MAKE_CMD=$(CC) -shared -Wl,-install_name,$(BSON_DYLIB_MINOR_NAME) -o $(BSON_DYLIBNAME) 125 | endif 126 | 127 | # Installation 128 | ifeq ($(kernel_name),SunOS) 129 | INSTALL?=cp -r 130 | endif 131 | INSTALL?= cp -a 132 | INSTALL_INCLUDE_PATH?=/usr/local/include 133 | INSTALL_LIBRARY_PATH?=/usr/local/lib 134 | 135 | # TARGETS 136 | all: $(MONGO_DYLIBNAME) $(BSON_DYLIBNAME) $(MONGO_STLIBNAME) $(BSON_STLIBNAME) 137 | 138 | # Dependency targets. Run 'make deps' to generate these. 139 | bson.o: src/bson.c src/bson.h src/encoding.h 140 | encoding.o: src/encoding.c src/bson.h src/encoding.h 141 | env_standard.o: src/env_standard.c src/env.h src/mongo.h src/bson.h 142 | env_posix.o: src/env_posix.c src/env.h src/mongo.h src/bson.h 143 | gridfs.o: src/gridfs.c src/gridfs.h src/mongo.h src/bson.h 144 | md5.o: src/md5.c src/md5.h 145 | mongo.o: src/mongo.c src/mongo.h src/bson.h src/md5.h src/env.h 146 | numbers.o: src/numbers.c 147 | 148 | $(MONGO_DYLIBNAME): $(DYN_MONGO_OBJECTS) 149 | $(MONGO_DYLIB_MAKE_CMD) 150 | 151 | $(MONGO_STLIBNAME): $(MONGO_OBJECTS) 152 | $(AR) -rs $@ $(MONGO_OBJECTS) 153 | 154 | $(BSON_DYLIBNAME): $(DYN_BSON_OBJECTS) 155 | $(BSON_DYLIB_MAKE_CMD) 156 | 157 | $(BSON_STLIBNAME): $(BSON_OBJECTS) 158 | $(AR) -rs $@ $(BSON_OBJECTS) 159 | 160 | install: 161 | mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH) 162 | $(INSTALL) src/mongo.h src/bson.h $(INSTALL_INCLUDE_PATH) 163 | $(INSTALL) $(MONGO_DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(MONGO_DYLIB_PATCH_NAME) 164 | $(INSTALL) $(BSON_DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(BSON_DYLIB_PATCH_NAME) 165 | cd $(INSTALL_LIBRARY_PATH) && ln -sf $(MONGO_DYLIB_PATCH_NAME) $(MONGO_DYLIB_MINOR_NAME) 166 | cd $(INSTALL_LIBRARY_PATH) && ln -sf $(BSON_DYLIB_PATCH_NAME) $(BSON_DYLIB_MINOR_NAME) 167 | cd $(INSTALL_LIBRARY_PATH) && ln -sf $(MONGO_DYLIB_MINOR_NAME) $(MONGO_DYLIBNAME) 168 | cd $(INSTALL_LIBRARY_PATH) && ln -sf $(BSON_DYLIB_MINOR_NAME) $(BSON_DYLIBNAME) 169 | $(INSTALL) $(MONGO_STLIBNAME) $(INSTALL_LIBRARY_PATH) 170 | $(INSTALL) $(BSON_STLIBNAME) $(INSTALL_LIBRARY_PATH) 171 | 172 | test: $(TESTS) 173 | sh runtests.sh 174 | 175 | valgrind: $(TESTS) 176 | sh runtests.sh -v 177 | 178 | docs: 179 | python docs/buildscripts/docs.py 180 | 181 | clean: 182 | rm -rf $(MONGO_DYLIBNAME) $(MONGO_STLIBNAME) $(BSON_DYLIBNAME) $(BSON_STLIBNAME) src/*.o src/*.os test/*_test 183 | 184 | deps: 185 | $(CC) -MM -DMONGO_HAVE_STDINT src/*.c 186 | 187 | 32bit: 188 | $(MAKE) CFLAGS="-m32" LDFLAGS="-pg" 189 | 190 | %_test: %_test.c $(MONGO_STLIBNAME) 191 | $(CC) -o $@ -L. -Isrc $(TEST_DEFINES) $(ALL_LDFLAGS) $< $(MONGO_STLIBNAME) 192 | 193 | %.o: %.c 194 | $(CC) -o $@ -c $(ALL_CFLAGS) $< 195 | 196 | %.os: %.c 197 | $(CC) -o $@ -c $(ALL_CFLAGS) $(DYN_FLAGS) $< 198 | 199 | .PHONY: clean docs test 200 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/HISTORY.md: -------------------------------------------------------------------------------- 1 | # MongoDB C Driver History 2 | 3 | ## 0.6 4 | 2012-6-3 5 | ** API CHANGE ** 6 | 7 | Version 0.6 supports write concern. This involves a backward-breaking 8 | API change, as the write functions now take an optional write_concern 9 | object. 10 | 11 | The driver now also supports the MONGO_CONTINUE_ON_ERROR flag for 12 | batch inserts. 13 | 14 | The new function prototypes are as follows: 15 | 16 | * int mongo_insert( mongo *conn, const char *ns, const bson *data, 17 | mongo_write_concern *custom_write_concern ); 18 | 19 | * int mongo_insert_batch( mongo *conn, const char *ns, 20 | const bson **data, int num, mongo_write_concern *custom_write_concern ); 21 | 22 | * int mongo_update( mongo *conn, const char *ns, const bson *cond, 23 | const bson *op, int flags, mongo_write_concern *custom_write_concern, 24 | int flags ); 25 | 26 | * int mongo_remove( mongo *conn, const char *ns, const bson *cond, 27 | mongo_write_concern *custom_write_concern ); 28 | 29 | * Allow DBRefs (i.e., allows keys $ref, $id, and $db) 30 | * Added mongo_create_capped_collection(). 31 | * Fixed some bugs in the SCons and Makefile build scripts. 32 | * Fixes for SCons and Makefile shared library install targets. 33 | * Other minor bug fixes. 34 | 35 | ## 0.5.2 36 | 2012-5-4 37 | 38 | * Validate collection and database names on insert. 39 | * Validate insert limits using max BSON size. 40 | * Support getaddrinfo and SO_RCVTIMEO and SO_SNDTIMEO on Windows. 41 | * Store errno/WSAGetLastError() on errors. 42 | * Various bug fixes and refactorings. 43 | * Update error reporting docs. 44 | 45 | ## 0.5.1 46 | 47 | * Env for POSIX, WIN32, and standard C. 48 | * Various bug fixes. 49 | 50 | ## 0.5 51 | 2012-3-31 52 | 53 | * Separate cursor-specific errors into their own enum: mongo_cursor_error_t. 54 | * Catch $err return on bad queries and store the result in conn->getlasterrorcode 55 | and conn->getlasterrstr. 56 | * On queries that return $err, set cursor->err to MONGO_CURSOR_QUERY_FAIL. 57 | * When passing bad BSON to a cursor object, set cursor->err to MONGO_CURSOR_BSON_ERROR, 58 | and store the specific BSON error on the conn->err field. 59 | * Remove bson_copy_basic(). 60 | * bson_copy() will copy finished bson objects only. 61 | * bson_copy() returns BSON_OK on success and BSON_ERROR on failure. 62 | * Added a Makefile for easy compile and install on Linux and OS X. 63 | * Replica set connect fixes. 64 | 65 | ## 0.4 66 | 67 | THIS RELEASE INCLUDES NUMEROUS BACKWARD-BREAKING CHANGES. 68 | These changes have been made for extensibility, consistency, 69 | and ease of use. Please read the following release notes 70 | carefully, and study the updated tutorial. 71 | 72 | API Principles: 73 | 74 | 1. Present a consistent interface for all objects: connections, 75 | cursors, bson objects, and bson iterators. 76 | 2. Require no knowledge of an object's implementation to use the API. 77 | 3. Allow users to allocate objects on the stack or on the heap. 78 | 4. Integrate API with new error reporting strategy. 79 | 5. Be concise, except where it impairs clarity. 80 | 81 | Changes: 82 | 83 | * mongo_replset_init_conn has been renamed to mongo_replset_init. 84 | * bson_buffer has been removed. All functions for building bson 85 | objects now take objects of type bson. The new pattern looks like this: 86 | 87 | Example: 88 | 89 | bson b[1]; 90 | bson_init( b ); 91 | bson_append_int( b, "foo", 1 ); 92 | bson_finish( b ); 93 | /* The object is ready to use. 94 | When finished, destroy it. */ 95 | bson_destroy( b ); 96 | 97 | * mongo_connection has been renamed to mongo. 98 | 99 | Example: 100 | 101 | mongo conn[1]; 102 | mongo_connect( conn, '127.0.0.1', 27017 ); 103 | /* Connection is ready. Destroy when down. */ 104 | mongo_destroy( conn ); 105 | 106 | * New cursor builder API for clearer code: 107 | 108 | Example: 109 | 110 | mongo_cursor cursor[1]; 111 | mongo_cursor_init( cursor, conn, "test.foo" ); 112 | 113 | bson query[1]; 114 | 115 | bson_init( query ); 116 | bson_append_int( query, "bar", 1 ); 117 | bson_finish( query ); 118 | 119 | bson fields[1]; 120 | 121 | bson_init( fields ); 122 | bson_append_int( fields, "baz", 1 ); 123 | bson_finish( fields ); 124 | 125 | mongo_cursor_set_query( cursor, query ); 126 | mongo_cursor_set_fields( cursor, fields ); 127 | mongo_cursor_set_limit( cursor, 10 ); 128 | mongo_cursor_set_skip( cursor, 10 ); 129 | 130 | while( mongo_cursor_next( cursor ) == MONGO_OK ) 131 | bson_print( mongo_cursor_bson( cursor ) ); 132 | 133 | * bson_iterator_init now takes a (bson*) instead of a (const char*). This is consistent 134 | with bson_find, which also takes a (bson*). If you want to initiate a bson iterator 135 | with a buffer, use the new function bson_iterator_from_buffer. 136 | * With the addition of the mongo_cursor_bson function, it's now no 137 | longer necessary to know how bson and mongo_cursor objects are implemented. 138 | 139 | Example: 140 | 141 | bson b[1]; 142 | bson_iterator i[1]; 143 | 144 | bson_iterator_init( i, b ); 145 | 146 | /* With a cursor */ 147 | bson_iterator_init( i, mongo_cursor_bson( cursor ) ); 148 | 149 | * Added mongo_cursor_data and bson_data functions, which return the 150 | raw bson buffer as a (const char *). 151 | * All constants that were once lower case are now 152 | upper case. These include: MONGO_OP_MSG, MONGO_OP_UPDATE, MONGO_OP_INSERT, 153 | MONGO_OP_QUERY, MONGO_OP_GET_MORE, MONGO_OP_DELETE, MONGO_OP_KILL_CURSORS 154 | BSON_EOO, BSON_DOUBLE, BSON_STRING, BSON_OBJECT, BSON_ARRAY, BSON_BINDATA, 155 | BSON_UNDEFINED, BSON_OID, BSON_BOOL, BSON_DATE, BSON_NULL, BSON_REGEX, BSON_DBREF, 156 | BSON_CODE, BSON_SYMBOL, BSON_CODEWSCOPE, BSON_INT, BSON_TIMESTAMP, BSON_LONG, 157 | MONGO_CONN_SUCCESS, MONGO_CONN_BAD_ARG, MONGO_CONN_NO_SOCKET, MONGO_CONN_FAIL, 158 | MONGO_CONN_NOT_MASTER, MONGO_CONN_BAD_SET_NAME, MONGO_CONN_CANNOT_FIND_PRIMARY 159 | If your programs use any of these constants, you must convert them to their 160 | upper case forms, or you will see compile errors. 161 | * The error handling strategy has been changed. Exceptions are not longer being used. 162 | * Functions taking a mongo_connection object now return either MONGO_OK or MONGO_ERROR. 163 | In case of an error, an error code of type mongo_error_t will be indicated on the 164 | mongo_connection->err field. 165 | * Functions taking a bson object now return either BSON_OK or BSON_ERROR. 166 | In case of an error, an error code of type bson_validity_t will be indicated on the 167 | bson->err or bson_buffer->err field. 168 | * Calls to mongo_cmd_get_last_error store the error status on the 169 | mongo->lasterrcode and mongo->lasterrstr fields. 170 | * bson_print now prints all types. 171 | * Users may now set custom malloc, realloc, free, printf, sprintf, and fprintf fields. 172 | * Groundwork for modules for supporting platform-specific features (e.g., socket timeouts). 173 | * Added mongo_set_op_timeout for setting socket timeout. To take advantage of this, you must 174 | compile with --use-platform=LINUX. The compiles with platform/linux/net.h instead of the 175 | top-level net.h. 176 | * Fixed tailable cursors. 177 | * GridFS API is now in-line with the new driver API. In particular, all of the 178 | following functions now return MONGO_OK or MONGO_ERROR: gridfs_init, 179 | gridfile_init, gridfile_writer_done, gridfs_store_buffer, gridfs_store_file, 180 | and gridfs_find_query. 181 | * Fixed a few memory leaks. 182 | 183 | ## 0.3 184 | 2011-4-14 185 | 186 | * Support replica sets. 187 | * Better standard connection API. 188 | * GridFS write buffers iteratively. 189 | * Fixes for working with large GridFS files (> 3GB) 190 | * bson_append_string_n and family (Gergely Nagy) 191 | 192 | ## 0.2 193 | 2011-2-11 194 | 195 | * GridFS support (Chris Triolo). 196 | * BSON Timestamp type support. 197 | 198 | ## 0.1 199 | 2009-11-30 200 | 201 | * Initial release. 202 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/docs/source/sphinx/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # MongoDB C Driver documentation build configuration file, created by 4 | # sphinx-quickstart on Wed Jun 22 12:23:03 2011. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys, os 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | #sys.path.insert(0, os.path.abspath('.')) 20 | 21 | # -- General configuration ----------------------------------------------------- 22 | 23 | # If your documentation needs a minimal Sphinx version, state it here. 24 | #needs_sphinx = '1.0' 25 | 26 | # Add any Sphinx extension module names here, as strings. They can be extensions 27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 28 | extensions = [] 29 | 30 | # Add any paths that contain templates here, relative to this directory. 31 | templates_path = ['_templates'] 32 | 33 | # The suffix of source filenames. 34 | source_suffix = '.rst' 35 | 36 | # The encoding of source files. 37 | #source_encoding = 'utf-8-sig' 38 | 39 | # The master toctree document. 40 | master_doc = 'index' 41 | 42 | # General information about the project. 43 | project = u'MongoDB C Driver' 44 | copyright = u'2011, 10gen' 45 | 46 | # The version info for the project you're documenting, acts as replacement for 47 | # |version| and |release|, also used in various other places throughout the 48 | # built documents. 49 | # 50 | # The short X.Y version. 51 | version = '0.4' 52 | # The full version, including alpha/beta/rc tags. 53 | release = '0.4' 54 | 55 | # The language for content autogenerated by Sphinx. Refer to documentation 56 | # for a list of supported languages. 57 | #language = None 58 | 59 | # There are two options for replacing |today|: either, you set today to some 60 | # non-false value, then it is used: 61 | #today = '' 62 | # Else, today_fmt is used as the format for a strftime call. 63 | #today_fmt = '%B %d, %Y' 64 | 65 | # List of patterns, relative to source directory, that match files and 66 | # directories to ignore when looking for source files. 67 | exclude_patterns = [] 68 | 69 | # The reST default role (used for this markup: `text`) to use for all documents. 70 | #default_role = None 71 | 72 | # If true, '()' will be appended to :func: etc. cross-reference text. 73 | #add_function_parentheses = True 74 | 75 | # If true, the current module name will be prepended to all description 76 | # unit titles (such as .. function::). 77 | #add_module_names = True 78 | 79 | # If true, sectionauthor and moduleauthor directives will be shown in the 80 | # output. They are ignored by default. 81 | #show_authors = False 82 | 83 | # The name of the Pygments (syntax highlighting) style to use. 84 | pygments_style = 'sphinx' 85 | 86 | # A list of ignored prefixes for module index sorting. 87 | #modindex_common_prefix = [] 88 | 89 | 90 | # -- Options for HTML output --------------------------------------------------- 91 | 92 | # The theme to use for HTML and HTML Help pages. See the documentation for 93 | # a list of builtin themes. 94 | # html_theme = 'nature' 95 | 96 | # Theme options are theme-specific and customize the look and feel of a theme 97 | # further. For a list of options available for each theme, see the 98 | # documentation. 99 | #html_theme_options = {} 100 | 101 | # Add any paths that contain custom themes here, relative to this directory. 102 | #html_theme_path = [] 103 | 104 | # The name for this set of Sphinx documents. If None, it defaults to 105 | # " v documentation". 106 | #html_title = None 107 | 108 | # A shorter title for the navigation bar. Default is the same as html_title. 109 | #html_short_title = None 110 | 111 | # The name of an image file (relative to this directory) to place at the top 112 | # of the sidebar. 113 | #html_logo = None 114 | 115 | # The name of an image file (within the static path) to use as favicon of the 116 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 117 | # pixels large. 118 | #html_favicon = None 119 | 120 | # Add any paths that contain custom static files (such as style sheets) here, 121 | # relative to this directory. They are copied after the builtin static files, 122 | # so a file named "default.css" will overwrite the builtin "default.css". 123 | html_static_path = ['_static'] 124 | 125 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 126 | # using the given strftime format. 127 | #html_last_updated_fmt = '%b %d, %Y' 128 | 129 | # If true, SmartyPants will be used to convert quotes and dashes to 130 | # typographically correct entities. 131 | #html_use_smartypants = True 132 | 133 | # Custom sidebar templates, maps document names to template names. 134 | #html_sidebars = {} 135 | 136 | # Additional templates that should be rendered to pages, maps page names to 137 | # template names. 138 | #html_additional_pages = {} 139 | 140 | # If false, no module index is generated. 141 | #html_domain_indices = True 142 | 143 | # If false, no index is generated. 144 | #html_use_index = True 145 | 146 | # If true, the index is split into individual pages for each letter. 147 | #html_split_index = False 148 | 149 | # If true, links to the reST sources are added to the pages. 150 | #html_show_sourcelink = True 151 | 152 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 153 | #html_show_sphinx = True 154 | 155 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 156 | #html_show_copyright = True 157 | 158 | # If true, an OpenSearch description file will be output, and all pages will 159 | # contain a tag referring to it. The value of this option must be the 160 | # base URL from which the finished HTML is served. 161 | #html_use_opensearch = '' 162 | 163 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 164 | #html_file_suffix = None 165 | 166 | # Output file base name for HTML help builder. 167 | htmlhelp_basename = 'MongoDBCDriverdoc' 168 | 169 | 170 | # -- Options for LaTeX output -------------------------------------------------- 171 | 172 | # The paper size ('letter' or 'a4'). 173 | #latex_paper_size = 'letter' 174 | 175 | # The font size ('10pt', '11pt' or '12pt'). 176 | #latex_font_size = '10pt' 177 | 178 | # Grouping the document tree into LaTeX files. List of tuples 179 | # (source start file, target name, title, author, documentclass [howto/manual]). 180 | latex_documents = [ 181 | ('index', 'MongoDBCDriver.tex', u'MongoDB C Driver Documentation', 182 | u'10gen', 'manual'), 183 | ] 184 | 185 | # The name of an image file (relative to this directory) to place at the top of 186 | # the title page. 187 | #latex_logo = None 188 | 189 | # For "manual" documents, if this is true, then toplevel headings are parts, 190 | # not chapters. 191 | #latex_use_parts = False 192 | 193 | # If true, show page references after internal links. 194 | #latex_show_pagerefs = False 195 | 196 | # If true, show URL addresses after external links. 197 | #latex_show_urls = False 198 | 199 | # Additional stuff for the LaTeX preamble. 200 | #latex_preamble = '' 201 | 202 | # Documents to append as an appendix to all manuals. 203 | #latex_appendices = [] 204 | 205 | # If false, no module index is generated. 206 | #latex_domain_indices = True 207 | 208 | 209 | # -- Options for manual page output -------------------------------------------- 210 | 211 | # One entry per manual page. List of tuples 212 | # (source start file, name, description, authors, manual section). 213 | #man_pages = [ 214 | # ('index', 'mongodbcdriver', u'MongoDB C Driver Documentation', 215 | # [u'10gen, Inc.'], 1) 216 | #] 217 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/src/numbers.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2009-2012 10gen Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | /* all the numbers that fit in a 4 byte string */ 17 | const char bson_numstrs[1000][4] = { 18 | "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 19 | "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", 20 | "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", 21 | "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", 22 | "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", 23 | "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", 24 | "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", 25 | "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", 26 | "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", 27 | "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", 28 | 29 | "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", 30 | "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", 31 | "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", 32 | "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", 33 | "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", 34 | "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", 35 | "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", 36 | "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", 37 | "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", 38 | "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", 39 | 40 | "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", 41 | "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", 42 | "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", 43 | "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", 44 | "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", 45 | "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", 46 | "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", 47 | "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", 48 | "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", 49 | "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", 50 | 51 | "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", 52 | "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", 53 | "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", 54 | "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", 55 | "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", 56 | "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", 57 | "360", "361", "362", "363", "364", "365", "366", "367", "368", "369", 58 | "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", 59 | "380", "381", "382", "383", "384", "385", "386", "387", "388", "389", 60 | "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", 61 | 62 | "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", 63 | "410", "411", "412", "413", "414", "415", "416", "417", "418", "419", 64 | "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", 65 | "430", "431", "432", "433", "434", "435", "436", "437", "438", "439", 66 | "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", 67 | "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", 68 | "460", "461", "462", "463", "464", "465", "466", "467", "468", "469", 69 | "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", 70 | "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", 71 | "490", "491", "492", "493", "494", "495", "496", "497", "498", "499", 72 | 73 | "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", 74 | "510", "511", "512", "513", "514", "515", "516", "517", "518", "519", 75 | "520", "521", "522", "523", "524", "525", "526", "527", "528", "529", 76 | "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", 77 | "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", 78 | "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", 79 | "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", 80 | "570", "571", "572", "573", "574", "575", "576", "577", "578", "579", 81 | "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", 82 | "590", "591", "592", "593", "594", "595", "596", "597", "598", "599", 83 | 84 | "600", "601", "602", "603", "604", "605", "606", "607", "608", "609", 85 | "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", 86 | "620", "621", "622", "623", "624", "625", "626", "627", "628", "629", 87 | "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", 88 | "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", 89 | "650", "651", "652", "653", "654", "655", "656", "657", "658", "659", 90 | "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", 91 | "670", "671", "672", "673", "674", "675", "676", "677", "678", "679", 92 | "680", "681", "682", "683", "684", "685", "686", "687", "688", "689", 93 | "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", 94 | 95 | "700", "701", "702", "703", "704", "705", "706", "707", "708", "709", 96 | "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", 97 | "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", 98 | "730", "731", "732", "733", "734", "735", "736", "737", "738", "739", 99 | "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", 100 | "750", "751", "752", "753", "754", "755", "756", "757", "758", "759", 101 | "760", "761", "762", "763", "764", "765", "766", "767", "768", "769", 102 | "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", 103 | "780", "781", "782", "783", "784", "785", "786", "787", "788", "789", 104 | "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", 105 | 106 | "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", 107 | "810", "811", "812", "813", "814", "815", "816", "817", "818", "819", 108 | "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", 109 | "830", "831", "832", "833", "834", "835", "836", "837", "838", "839", 110 | "840", "841", "842", "843", "844", "845", "846", "847", "848", "849", 111 | "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", 112 | "860", "861", "862", "863", "864", "865", "866", "867", "868", "869", 113 | "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", 114 | "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", 115 | "890", "891", "892", "893", "894", "895", "896", "897", "898", "899", 116 | 117 | "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", 118 | "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", 119 | "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", 120 | "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", 121 | "940", "941", "942", "943", "944", "945", "946", "947", "948", "949", 122 | "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", 123 | "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", 124 | "970", "971", "972", "973", "974", "975", "976", "977", "978", "979", 125 | "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", 126 | "990", "991", "992", "993", "994", "995", "996", "997", "998", "999", 127 | }; 128 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/gridfs_test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "md5.h" 3 | #include "mongo.h" 4 | #include "gridfs.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #ifndef _WIN32 10 | #include 11 | #endif 12 | 13 | #define LARGE 3*1024*1024 14 | #define UPPER 2000*1024 15 | #define MEDIUM 1024*512 16 | #define LOWER 1024*128 17 | #define DELTA 1024*128 18 | 19 | void fill_buffer_randomly( char *data, int64_t length ) { 20 | int64_t i; 21 | int random; 22 | char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 23 | int nletters = strlen( letters )+1; 24 | 25 | for ( i = 0; i < length; i++ ) { 26 | random = rand() % nletters; 27 | *( data + i ) = letters[random]; 28 | } 29 | } 30 | 31 | static void digest2hex( mongo_md5_byte_t digest[16], char hex_digest[33] ) { 32 | static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; 33 | int i; 34 | for ( i=0; i<16; i++ ) { 35 | hex_digest[2*i] = hex[( digest[i] & 0xf0 ) >> 4]; 36 | hex_digest[2*i + 1] = hex[ digest[i] & 0x0f ]; 37 | } 38 | hex_digest[32] = '\0'; 39 | } 40 | 41 | void test_gridfile( gridfs *gfs, char *data_before, int64_t length, char *filename, char *content_type ) { 42 | gridfile gfile[1]; 43 | FILE *stream; 44 | mongo_md5_state_t pms[1]; 45 | mongo_md5_byte_t digest[16]; 46 | char hex_digest[33]; 47 | int64_t i = length; 48 | int n; 49 | char *data_after = bson_malloc( LARGE ); 50 | 51 | gridfs_find_filename( gfs, filename, gfile ); 52 | ASSERT( gridfile_exists( gfile ) ); 53 | 54 | stream = fopen( "output", "w+" ); 55 | gridfile_write_file( gfile, stream ); 56 | fseek( stream, 0, SEEK_SET ); 57 | ASSERT( fread( data_after, length, sizeof( char ), stream ) ); 58 | fclose( stream ); 59 | ASSERT( strncmp( data_before, data_after, length ) == 0 ); 60 | 61 | gridfile_read( gfile, length, data_after ); 62 | ASSERT( strncmp( data_before, data_after, length ) == 0 ); 63 | 64 | ASSERT( strcmp( gridfile_get_filename( gfile ), filename ) == 0 ); 65 | 66 | ASSERT( gridfile_get_contentlength( gfile ) == length ); 67 | 68 | ASSERT( gridfile_get_chunksize( gfile ) == DEFAULT_CHUNK_SIZE ); 69 | 70 | ASSERT( strcmp( gridfile_get_contenttype( gfile ), content_type ) == 0 ) ; 71 | 72 | ASSERT( strncmp( data_before, data_after, length ) == 0 ); 73 | 74 | mongo_md5_init( pms ); 75 | 76 | n = 0; 77 | while( i > INT_MAX ) { 78 | mongo_md5_append( pms, ( const mongo_md5_byte_t * )data_before + ( n * INT_MAX ), INT_MAX ); 79 | i -= INT_MAX; 80 | n += 1; 81 | } 82 | if( i > 0 ) 83 | mongo_md5_append( pms, ( const mongo_md5_byte_t * )data_before + ( n * INT_MAX ), i ); 84 | 85 | mongo_md5_finish( pms, digest ); 86 | digest2hex( digest, hex_digest ); 87 | ASSERT( strcmp( gridfile_get_md5( gfile ), hex_digest ) == 0 ); 88 | 89 | gridfile_destroy( gfile ); 90 | gridfs_remove_filename( gfs, filename ); 91 | free( data_after ); 92 | unlink( "output" ); 93 | } 94 | 95 | void test_basic() { 96 | mongo conn[1]; 97 | gridfs gfs[1]; 98 | char *data_before = bson_malloc( UPPER ); 99 | int64_t i; 100 | FILE *fd; 101 | 102 | srand( time( NULL ) ); 103 | 104 | INIT_SOCKETS_FOR_WINDOWS; 105 | 106 | if ( mongo_connect( conn, TEST_SERVER, 27017 ) ) { 107 | printf( "failed to connect 2\n" ); 108 | exit( 1 ); 109 | } 110 | 111 | gridfs_init( conn, "test", "fs", gfs ); 112 | 113 | fill_buffer_randomly( data_before, UPPER ); 114 | for ( i = LOWER; i <= UPPER; i += DELTA ) { 115 | 116 | /* Input from buffer */ 117 | gridfs_store_buffer( gfs, data_before, i, "input-buffer", "text/html" ); 118 | test_gridfile( gfs, data_before, i, "input-buffer", "text/html" ); 119 | 120 | /* Input from file */ 121 | fd = fopen( "input-file", "w" ); 122 | fwrite( data_before, sizeof( char ), i, fd ); 123 | fclose( fd ); 124 | gridfs_store_file( gfs, "input-file", "input-file", "text/html" ); 125 | test_gridfile( gfs, data_before, i, "input-file", "text/html" ); 126 | } 127 | 128 | gridfs_destroy( gfs ); 129 | mongo_disconnect( conn ); 130 | mongo_destroy( conn ); 131 | free( data_before ); 132 | 133 | /* Clean up files. */ 134 | unlink( "input-file" ); 135 | unlink( "output" ); 136 | } 137 | 138 | void test_streaming() { 139 | mongo conn[1]; 140 | gridfs gfs[1]; 141 | gridfile gfile[1]; 142 | char *medium = bson_malloc( 2*MEDIUM ); 143 | char *small = bson_malloc( LOWER ); 144 | char *buf = bson_malloc( LARGE ); 145 | int n; 146 | 147 | if( buf == NULL || small == NULL ) { 148 | printf( "Failed to allocate" ); 149 | exit( 1 ); 150 | } 151 | 152 | srand( time( NULL ) ); 153 | 154 | INIT_SOCKETS_FOR_WINDOWS; 155 | 156 | if ( mongo_connect( conn , TEST_SERVER, 27017 ) ) { 157 | printf( "failed to connect 3\n" ); 158 | exit( 1 ); 159 | } 160 | 161 | fill_buffer_randomly( medium, ( int64_t )2 * MEDIUM ); 162 | fill_buffer_randomly( small, ( int64_t )LOWER ); 163 | fill_buffer_randomly( buf, ( int64_t )LARGE ); 164 | 165 | gridfs_init( conn, "test", "fs", gfs ); 166 | gridfile_writer_init( gfile, gfs, "medium", "text/html" ); 167 | 168 | gridfile_write_buffer( gfile, medium, MEDIUM ); 169 | gridfile_write_buffer( gfile, medium + MEDIUM, MEDIUM ); 170 | gridfile_writer_done( gfile ); 171 | test_gridfile( gfs, medium, 2 * MEDIUM, "medium", "text/html" ); 172 | gridfs_destroy( gfs ); 173 | 174 | gridfs_init( conn, "test", "fs", gfs ); 175 | 176 | gridfs_store_buffer( gfs, small, LOWER, "small", "text/html" ); 177 | test_gridfile( gfs, small, LOWER, "small", "text/html" ); 178 | gridfs_destroy( gfs ); 179 | 180 | gridfs_init( conn, "test", "fs", gfs ); 181 | gridfile_writer_init( gfile, gfs, "large", "text/html" ); 182 | for( n=0; n < ( LARGE / 1024 ); n++ ) { 183 | gridfile_write_buffer( gfile, buf + ( n * 1024 ), 1024 ); 184 | } 185 | gridfile_writer_done( gfile ); 186 | test_gridfile( gfs, buf, LARGE, "large", "text/html" ); 187 | 188 | gridfs_destroy( gfs ); 189 | mongo_destroy( conn ); 190 | free( buf ); 191 | free( small ); 192 | } 193 | 194 | void test_large() { 195 | mongo conn[1]; 196 | gridfs gfs[1]; 197 | gridfile gfile[1]; 198 | FILE *fd; 199 | int i, n; 200 | char *buffer = bson_malloc( LARGE ); 201 | int64_t filesize = ( int64_t )1024 * ( int64_t )LARGE; 202 | 203 | srand( time( NULL ) ); 204 | 205 | INIT_SOCKETS_FOR_WINDOWS; 206 | 207 | if ( mongo_connect( conn, TEST_SERVER, 27017 ) ) { 208 | printf( "failed to connect 1\n" ); 209 | exit( 1 ); 210 | } 211 | 212 | gridfs_init( conn, "test", "fs", gfs ); 213 | 214 | /* Create a very large file */ 215 | fill_buffer_randomly( buffer, ( int64_t )LARGE ); 216 | fd = fopen( "bigfile", "w" ); 217 | for( i=0; i<1024; i++ ) { 218 | fwrite( buffer, 1, LARGE, fd ); 219 | } 220 | fclose( fd ); 221 | 222 | /* Now read the file into GridFS */ 223 | gridfs_store_file( gfs, "bigfile", "bigfile", "text/html" ); 224 | 225 | gridfs_find_filename( gfs, "bigfile", gfile ); 226 | 227 | ASSERT( strcmp( gridfile_get_filename( gfile ), "bigfile" ) == 0 ); 228 | ASSERT( gridfile_get_contentlength( gfile ) == filesize ); 229 | 230 | /* Read the file using the streaming interface */ 231 | gridfile_writer_init( gfile, gfs, "bigfile-stream", "text/html" ); 232 | 233 | fd = fopen( "bigfile", "r" ); 234 | 235 | while( ( n = fread( buffer, 1, 1024, fd ) ) != 0 ) { 236 | gridfile_write_buffer( gfile, buffer, n ); 237 | } 238 | gridfile_writer_done( gfile ); 239 | 240 | gridfs_find_filename( gfs, "bigfile-stream", gfile ); 241 | 242 | ASSERT( strcmp( gridfile_get_filename( gfile ), "bigfile-stream" ) == 0 ); 243 | ASSERT( gridfile_get_contentlength( gfile ) == filesize ); 244 | 245 | gridfs_destroy( gfs ); 246 | mongo_disconnect( conn ); 247 | mongo_destroy( conn ); 248 | } 249 | 250 | int main( void ) { 251 | /* See https://jira.mongodb.org/browse/CDRIVER-126 252 | * on why we exclude this test from running on WIN32 */ 253 | #ifndef _WIN32 254 | test_basic(); 255 | test_streaming(); 256 | #endif 257 | 258 | /* Normally not necessary to run test_large(), as it 259 | * deals with very large (3GB) files and is therefore slow. 260 | * test_large(); 261 | */ 262 | return 0; 263 | } 264 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/errors_test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "mongo.h" 3 | #include 4 | #include 5 | #include 6 | 7 | static const char *db = "test"; 8 | static const char *ns = "test.c.error"; 9 | 10 | int test_namespace_validation() { 11 | mongo conn[1]; 12 | char longns[130] = "test.foo"; 13 | int i; 14 | 15 | mongo_init( conn ); 16 | 17 | /* Test a few legal namespaces. */ 18 | ASSERT( mongo_validate_ns( conn, "test.foo" ) == MONGO_OK ); 19 | ASSERT( conn->err == 0 ); 20 | 21 | ASSERT( mongo_validate_ns( conn, "test.foo.bar" ) == MONGO_OK ); 22 | ASSERT( conn->err == 0 ); 23 | 24 | /* Test illegal namespaces. */ 25 | ASSERT( mongo_validate_ns( conn, ".test.foo" ) == MONGO_ERROR ); 26 | ASSERT( conn->err == MONGO_NS_INVALID ); 27 | ASSERT( strncmp( conn->errstr, "ns cannot start with", 20 ) == 0 ); 28 | mongo_clear_errors( conn ); 29 | 30 | ASSERT( mongo_validate_ns( conn, "test..foo" ) == MONGO_ERROR ); 31 | ASSERT( conn->err == MONGO_NS_INVALID ); 32 | ASSERT( strncmp( conn->errstr, "ns cannot start with", 20 ) == 0 ); 33 | mongo_clear_errors( conn ); 34 | 35 | ASSERT( mongo_validate_ns( conn, "test" ) == MONGO_ERROR ); 36 | ASSERT( conn->err == MONGO_NS_INVALID ); 37 | ASSERT( strncmp( conn->errstr, "ns cannot start with", 20 ) == 0 ); 38 | mongo_clear_errors( conn ); 39 | 40 | ASSERT( mongo_validate_ns( conn, "." ) == MONGO_ERROR ); 41 | ASSERT( conn->err == MONGO_NS_INVALID ); 42 | ASSERT( strncmp( conn->errstr, "ns cannot start with", 20 ) == 0 ); 43 | mongo_clear_errors( conn ); 44 | 45 | ASSERT( mongo_validate_ns( conn, "tes t.foo" ) == MONGO_ERROR ); 46 | ASSERT( conn->err == MONGO_NS_INVALID ); 47 | ASSERT( strncmp( conn->errstr, "Database name may not contain", 28 ) == 0 ); 48 | mongo_clear_errors( conn ); 49 | 50 | ASSERT( mongo_validate_ns( conn, "te$st.foo" ) == MONGO_ERROR ); 51 | ASSERT( conn->err == MONGO_NS_INVALID ); 52 | ASSERT( strncmp( conn->errstr, "Database name may not contain", 28 ) == 0 ); 53 | mongo_clear_errors( conn ); 54 | 55 | ASSERT( mongo_validate_ns( conn, "te/st.foo" ) == MONGO_ERROR ); 56 | ASSERT( conn->err == MONGO_NS_INVALID ); 57 | ASSERT( strncmp( conn->errstr, "Database name may not contain", 28 ) == 0 ); 58 | mongo_clear_errors( conn ); 59 | 60 | ASSERT( mongo_validate_ns( conn, "te\\st.foo" ) == MONGO_ERROR ); 61 | ASSERT( conn->err == MONGO_NS_INVALID ); 62 | ASSERT( strncmp( conn->errstr, "Database name may not contain", 28 ) == 0 ); 63 | mongo_clear_errors( conn ); 64 | 65 | ASSERT( mongo_validate_ns( conn, "test.fo$o" ) == MONGO_ERROR ); 66 | ASSERT( conn->err == MONGO_NS_INVALID ); 67 | ASSERT( strncmp( conn->errstr, "Collection may not contain '$'", 29 ) == 0 ); 68 | mongo_clear_errors( conn ); 69 | 70 | ASSERT( mongo_validate_ns( conn, "test.fo..o" ) == MONGO_ERROR ); 71 | ASSERT( conn->err == MONGO_NS_INVALID ); 72 | ASSERT( strncmp( conn->errstr, "Collection may not contain two consecutive '.'", 46 ) == 0 ); 73 | mongo_clear_errors( conn ); 74 | 75 | ASSERT( mongo_validate_ns( conn, "test.fo.o." ) == MONGO_ERROR ); 76 | ASSERT( conn->err == MONGO_NS_INVALID ); 77 | ASSERT( strncmp( conn->errstr, "Collection may not end with '.'", 30 ) == 0 ); 78 | mongo_clear_errors( conn ); 79 | 80 | for(i = 8; i < 129; i++ ) 81 | longns[i] = 'a'; 82 | longns[129] = '\0'; 83 | 84 | ASSERT( mongo_validate_ns( conn, longns ) == MONGO_ERROR ); 85 | ASSERT( conn->err == MONGO_NS_INVALID ); 86 | ASSERT( strncmp( conn->errstr, "Namespace too long; has 129 but must <= 128.", 32 ) == 0 ); 87 | mongo_clear_errors( conn ); 88 | 89 | return 0; 90 | } 91 | 92 | int test_namespace_validation_on_insert( void ) { 93 | mongo conn[1]; 94 | bson b[1], b2[1]; 95 | bson *objs[2]; 96 | 97 | INIT_SOCKETS_FOR_WINDOWS; 98 | 99 | if ( mongo_connect( conn , TEST_SERVER, 27017 ) ) { 100 | printf( "failed to connect\n" ); 101 | exit( 1 ); 102 | } 103 | 104 | bson_init( b ); 105 | bson_append_int( b, "foo", 1 ); 106 | bson_finish( b ); 107 | 108 | ASSERT( mongo_insert( conn, "tet.fo$o", b, NULL ) == MONGO_ERROR ); 109 | ASSERT( conn->err == MONGO_NS_INVALID ); 110 | ASSERT( strncmp( conn->errstr, "Collection may not contain '$'", 29 ) == 0 ); 111 | mongo_clear_errors( conn ); 112 | 113 | bson_init( b2 ); 114 | bson_append_int( b2, "foo", 1 ); 115 | bson_finish( b2 ); 116 | 117 | objs[0] = b; 118 | objs[1] = b2; 119 | 120 | ASSERT( mongo_insert_batch( conn, "tet.fo$o", 121 | (const bson **)objs, 2, NULL, 0 ) == MONGO_ERROR ); 122 | ASSERT( conn->err == MONGO_NS_INVALID ); 123 | ASSERT( strncmp( conn->errstr, "Collection may not contain '$'", 29 ) == 0 ); 124 | 125 | return 0; 126 | } 127 | 128 | int test_insert_limits( void ) { 129 | char version[10]; 130 | mongo conn[1]; 131 | int i; 132 | char key[10]; 133 | bson b[1], b2[1]; 134 | bson *objs[2]; 135 | 136 | /* Test the default max BSON size. */ 137 | mongo_init( conn ); 138 | ASSERT( conn->max_bson_size == MONGO_DEFAULT_MAX_BSON_SIZE ); 139 | 140 | /* We'll perform the full test if we're running v2.0 or later. */ 141 | if( mongo_get_server_version( version ) != -1 && version[0] <= '1' ) 142 | return 0; 143 | 144 | if ( mongo_connect( conn , TEST_SERVER, 27017 ) ) { 145 | printf( "failed to connect\n" ); 146 | exit( 1 ); 147 | } 148 | 149 | ASSERT( conn->max_bson_size > MONGO_DEFAULT_MAX_BSON_SIZE ); 150 | 151 | bson_init( b ); 152 | for(i=0; i<1200000; i++) { 153 | sprintf( key, "%d", i + 10000000 ); 154 | bson_append_int( b, key, i ); 155 | } 156 | bson_finish( b ); 157 | 158 | ASSERT( bson_size( b ) > conn->max_bson_size ); 159 | 160 | ASSERT( mongo_insert( conn, "test.foo", b, NULL ) == MONGO_ERROR ); 161 | ASSERT( conn->err == MONGO_BSON_TOO_LARGE ); 162 | 163 | mongo_clear_errors( conn ); 164 | ASSERT( conn->err == 0 ); 165 | 166 | bson_init( b2 ); 167 | bson_append_int( b2, "foo", 1 ); 168 | bson_finish( b2 ); 169 | 170 | objs[0] = b; 171 | objs[1] = b2; 172 | 173 | ASSERT( mongo_insert_batch( conn, "test.foo", (const bson **)objs, 2, 174 | NULL, 0 ) == MONGO_ERROR ); 175 | ASSERT( conn->err == MONGO_BSON_TOO_LARGE ); 176 | 177 | return 0; 178 | } 179 | 180 | int test_get_last_error_commands( void ) { 181 | mongo conn[1]; 182 | bson obj; 183 | 184 | INIT_SOCKETS_FOR_WINDOWS; 185 | 186 | if ( mongo_connect( conn , TEST_SERVER, 27017 ) ) { 187 | printf( "failed to connect\n" ); 188 | exit( 1 ); 189 | } 190 | 191 | /*********************/ 192 | ASSERT( mongo_cmd_get_prev_error( conn, db, NULL ) == MONGO_OK ); 193 | ASSERT( conn->lasterrcode == 0 ); 194 | ASSERT( conn->lasterrstr[0] == 0 ); 195 | 196 | ASSERT( mongo_cmd_get_last_error( conn, db, NULL ) == MONGO_OK ); 197 | ASSERT( conn->lasterrcode == 0 ); 198 | ASSERT( conn->lasterrstr[0] == 0 ); 199 | 200 | ASSERT( mongo_cmd_get_prev_error( conn, db, &obj ) == MONGO_OK ); 201 | bson_destroy( &obj ); 202 | 203 | ASSERT( mongo_cmd_get_last_error( conn, db, &obj ) == MONGO_OK ); 204 | bson_destroy( &obj ); 205 | 206 | /*********************/ 207 | mongo_simple_int_command( conn, db, "forceerror", 1, NULL ); 208 | 209 | ASSERT( mongo_cmd_get_prev_error( conn, db, NULL ) == MONGO_ERROR ); 210 | ASSERT( conn->lasterrcode == 10038 ); 211 | ASSERT( strcmp( ( const char * )conn->lasterrstr, "forced error" ) == 0 ); 212 | 213 | ASSERT( mongo_cmd_get_last_error( conn, db, NULL ) == MONGO_ERROR ); 214 | 215 | ASSERT( mongo_cmd_get_prev_error( conn, db, &obj ) == MONGO_ERROR ); 216 | bson_destroy( &obj ); 217 | 218 | ASSERT( mongo_cmd_get_last_error( conn, db, &obj ) == MONGO_ERROR ); 219 | bson_destroy( &obj ); 220 | 221 | /* should clear lasterror but not preverror */ 222 | mongo_find_one( conn, ns, bson_empty( &obj ), bson_empty( &obj ), NULL ); 223 | 224 | ASSERT( mongo_cmd_get_prev_error( conn, db, NULL ) == MONGO_ERROR ); 225 | ASSERT( mongo_cmd_get_last_error( conn, db, NULL ) == MONGO_OK ); 226 | 227 | ASSERT( mongo_cmd_get_prev_error( conn, db, &obj ) == MONGO_ERROR ); 228 | bson_destroy( &obj ); 229 | 230 | ASSERT( mongo_cmd_get_last_error( conn, db, &obj ) == MONGO_OK ); 231 | bson_destroy( &obj ); 232 | 233 | /*********************/ 234 | mongo_cmd_reset_error( conn, db ); 235 | 236 | ASSERT( mongo_cmd_get_prev_error( conn, db, NULL ) == MONGO_OK ); 237 | ASSERT( mongo_cmd_get_last_error( conn, db, NULL ) == MONGO_OK ); 238 | 239 | ASSERT( mongo_cmd_get_prev_error( conn, db, &obj ) == MONGO_OK ); 240 | bson_destroy( &obj ); 241 | 242 | ASSERT( mongo_cmd_get_last_error( conn, db, &obj ) == MONGO_OK ); 243 | bson_destroy( &obj ); 244 | 245 | 246 | mongo_cmd_drop_db( conn, db ); 247 | mongo_destroy( conn ); 248 | 249 | return 0; 250 | } 251 | 252 | int main() { 253 | test_get_last_error_commands(); 254 | test_insert_limits(); 255 | test_namespace_validation(); 256 | test_namespace_validation_on_insert(); 257 | 258 | return 0; 259 | } 260 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/bson_test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "bson.h" 3 | #include 4 | #include 5 | #include 6 | 7 | int test_bson_generic() { 8 | 9 | bson_iterator it, it2, it3; 10 | bson_oid_t oid; 11 | bson_timestamp_t ts; 12 | bson_timestamp_t ts_result; 13 | bson b[1]; 14 | bson copy[1]; 15 | bson scope[1]; 16 | 17 | ts.i = 1; 18 | ts.t = 2; 19 | 20 | bson_init( b ); 21 | bson_append_double( b, "d", 3.14 ); 22 | bson_append_string( b, "s", "hello" ); 23 | bson_append_string_n( b, "s_n", "goodbye cruel world", 7 ); 24 | 25 | { 26 | bson_append_start_object( b, "o" ); 27 | bson_append_start_array( b, "a" ); 28 | bson_append_binary( b, "0", 8, "w\0rld", 5 ); 29 | bson_append_finish_object( b ); 30 | bson_append_finish_object( b ); 31 | } 32 | 33 | bson_append_undefined( b, "u" ); 34 | 35 | bson_oid_from_string( &oid, "010203040506070809101112" ); 36 | ASSERT( !memcmp( oid.bytes, "\x001\x002\x003\x004\x005\x006\x007\x008\x009\x010\x011\x012", 12 ) ); 37 | bson_append_oid( b, "oid", &oid ); 38 | 39 | bson_append_bool( b, "b", 1 ); 40 | bson_append_date( b, "date", 0x0102030405060708 ); 41 | bson_append_null( b, "n" ); 42 | bson_append_regex( b, "r", "^asdf", "imx" ); 43 | /* no dbref test (deprecated) */ 44 | bson_append_code( b, "c", "function(){}" ); 45 | bson_append_code_n( b, "c_n", "function(){}garbage", 12 ); 46 | bson_append_symbol( b, "symbol", "symbol" ); 47 | bson_append_symbol_n( b, "symbol_n", "symbol and garbage", 6 ); 48 | 49 | { 50 | bson_init( scope ); 51 | bson_append_int( scope, "i", 123 ); 52 | bson_finish( scope ); 53 | 54 | bson_append_code_w_scope( b, "cws", "function(){return i}", scope ); 55 | bson_destroy( scope ); 56 | } 57 | 58 | bson_append_timestamp( b, "timestamp", &ts ); 59 | bson_append_long( b, "l", 0x1122334455667788 ); 60 | 61 | /* Ensure that we can't copy a non-finished object. */ 62 | ASSERT( bson_copy( copy, b ) == BSON_ERROR ); 63 | 64 | bson_finish( b ); 65 | 66 | ASSERT( b->err == BSON_VALID ); 67 | 68 | /* Test append after finish. */ 69 | ASSERT( bson_append_string( b, "foo", "bar" ) == BSON_ERROR ); 70 | ASSERT( b->err & BSON_ALREADY_FINISHED ); 71 | 72 | ASSERT( bson_copy( copy, b ) == BSON_OK ); 73 | 74 | ASSERT( 1 == copy->finished ); 75 | ASSERT( 0 == copy->err ); 76 | 77 | bson_print( b ); 78 | 79 | bson_iterator_init( &it, b ); 80 | 81 | ASSERT( bson_iterator_more( &it ) ); 82 | ASSERT( bson_iterator_next( &it ) == BSON_DOUBLE ); 83 | ASSERT( bson_iterator_type( &it ) == BSON_DOUBLE ); 84 | ASSERT( !strcmp( bson_iterator_key( &it ), "d" ) ); 85 | ASSERT( bson_iterator_double( &it ) == 3.14 ); 86 | 87 | ASSERT( bson_iterator_more( &it ) ); 88 | ASSERT( bson_iterator_next( &it ) == BSON_STRING ); 89 | ASSERT( bson_iterator_type( &it ) == BSON_STRING ); 90 | ASSERT( !strcmp( bson_iterator_key( &it ), "s" ) ); 91 | ASSERT( !strcmp( bson_iterator_string( &it ), "hello" ) ); 92 | ASSERT( strcmp( bson_iterator_string( &it ), "" ) ); 93 | 94 | ASSERT( bson_iterator_more( &it ) ); 95 | ASSERT( bson_iterator_next( &it ) == BSON_STRING ); 96 | ASSERT( bson_iterator_type( &it ) == BSON_STRING ); 97 | ASSERT( !strcmp( bson_iterator_key( &it ), "s_n" ) ); 98 | ASSERT( !strcmp( bson_iterator_string( &it ), "goodbye" ) ); 99 | 100 | ASSERT( bson_iterator_more( &it ) ); 101 | ASSERT( bson_iterator_next( &it ) == BSON_OBJECT ); 102 | ASSERT( bson_iterator_type( &it ) == BSON_OBJECT ); 103 | ASSERT( !strcmp( bson_iterator_key( &it ), "o" ) ); 104 | bson_iterator_subiterator( &it, &it2 ); 105 | 106 | ASSERT( bson_iterator_more( &it2 ) ); 107 | ASSERT( bson_iterator_next( &it2 ) == BSON_ARRAY ); 108 | ASSERT( bson_iterator_type( &it2 ) == BSON_ARRAY ); 109 | ASSERT( !strcmp( bson_iterator_key( &it2 ), "a" ) ); 110 | bson_iterator_subiterator( &it2, &it3 ); 111 | 112 | ASSERT( bson_iterator_more( &it3 ) ); 113 | ASSERT( bson_iterator_next( &it3 ) == BSON_BINDATA ); 114 | ASSERT( bson_iterator_type( &it3 ) == BSON_BINDATA ); 115 | ASSERT( !strcmp( bson_iterator_key( &it3 ), "0" ) ); 116 | ASSERT( bson_iterator_bin_type( &it3 ) == 8 ); 117 | ASSERT( bson_iterator_bin_len( &it3 ) == 5 ); 118 | ASSERT( !memcmp( bson_iterator_bin_data( &it3 ), "w\0rld", 5 ) ); 119 | 120 | ASSERT( bson_iterator_more( &it3 ) ); 121 | ASSERT( bson_iterator_next( &it3 ) == BSON_EOO ); 122 | ASSERT( bson_iterator_type( &it3 ) == BSON_EOO ); 123 | ASSERT( !bson_iterator_more( &it3 ) ); 124 | 125 | ASSERT( bson_iterator_more( &it2 ) ); 126 | ASSERT( bson_iterator_next( &it2 ) == BSON_EOO ); 127 | ASSERT( bson_iterator_type( &it2 ) == BSON_EOO ); 128 | ASSERT( !bson_iterator_more( &it2 ) ); 129 | 130 | ASSERT( bson_iterator_more( &it ) ); 131 | ASSERT( bson_iterator_next( &it ) == BSON_UNDEFINED ); 132 | ASSERT( bson_iterator_type( &it ) == BSON_UNDEFINED ); 133 | ASSERT( !strcmp( bson_iterator_key( &it ), "u" ) ); 134 | 135 | ASSERT( bson_iterator_more( &it ) ); 136 | ASSERT( bson_iterator_next( &it ) == BSON_OID ); 137 | ASSERT( bson_iterator_type( &it ) == BSON_OID ); 138 | ASSERT( !strcmp( bson_iterator_key( &it ), "oid" ) ); 139 | ASSERT( !memcmp( bson_iterator_oid( &it )->bytes, "\x001\x002\x003\x004\x005\x006\x007\x008\x009\x010\x011\x012", 12 ) ); 140 | ASSERT( bson_iterator_oid( &it )->ints[0] == oid.ints[0] ); 141 | ASSERT( bson_iterator_oid( &it )->ints[1] == oid.ints[1] ); 142 | ASSERT( bson_iterator_oid( &it )->ints[2] == oid.ints[2] ); 143 | 144 | ASSERT( bson_iterator_more( &it ) ); 145 | ASSERT( bson_iterator_next( &it ) == BSON_BOOL ); 146 | ASSERT( bson_iterator_type( &it ) == BSON_BOOL ); 147 | ASSERT( !strcmp( bson_iterator_key( &it ), "b" ) ); 148 | ASSERT( bson_iterator_bool( &it ) == 1 ); 149 | 150 | ASSERT( bson_iterator_more( &it ) ); 151 | ASSERT( bson_iterator_next( &it ) == BSON_DATE ); 152 | ASSERT( bson_iterator_type( &it ) == BSON_DATE ); 153 | ASSERT( !strcmp( bson_iterator_key( &it ), "date" ) ); 154 | ASSERT( bson_iterator_date( &it ) == 0x0102030405060708 ); 155 | 156 | ASSERT( bson_iterator_more( &it ) ); 157 | ASSERT( bson_iterator_next( &it ) == BSON_NULL ); 158 | ASSERT( bson_iterator_type( &it ) == BSON_NULL ); 159 | ASSERT( !strcmp( bson_iterator_key( &it ), "n" ) ); 160 | 161 | ASSERT( bson_iterator_more( &it ) ); 162 | ASSERT( bson_iterator_next( &it ) == BSON_REGEX ); 163 | ASSERT( bson_iterator_type( &it ) == BSON_REGEX ); 164 | ASSERT( !strcmp( bson_iterator_key( &it ), "r" ) ); 165 | ASSERT( !strcmp( bson_iterator_regex( &it ), "^asdf" ) ); 166 | ASSERT( !strcmp( bson_iterator_regex_opts( &it ), "imx" ) ); 167 | 168 | ASSERT( bson_iterator_more( &it ) ); 169 | ASSERT( bson_iterator_next( &it ) == BSON_CODE ); 170 | ASSERT( bson_iterator_type( &it ) == BSON_CODE ); 171 | ASSERT( !strcmp( bson_iterator_code(&it), "function(){}") ); 172 | ASSERT( !strcmp( bson_iterator_key( &it ), "c" ) ); 173 | ASSERT( !strcmp( bson_iterator_string( &it ), "" ) ); 174 | 175 | ASSERT( bson_iterator_more( &it ) ); 176 | ASSERT( bson_iterator_next( &it ) == BSON_CODE ); 177 | ASSERT( bson_iterator_type( &it ) == BSON_CODE ); 178 | ASSERT( !strcmp( bson_iterator_key( &it ), "c_n" ) ); 179 | ASSERT( !strcmp( bson_iterator_string( &it ), "" ) ); 180 | ASSERT( !strcmp( bson_iterator_code( &it ), "function(){}" ) ); 181 | 182 | ASSERT( bson_iterator_more( &it ) ); 183 | ASSERT( bson_iterator_next( &it ) == BSON_SYMBOL ); 184 | ASSERT( bson_iterator_type( &it ) == BSON_SYMBOL ); 185 | ASSERT( !strcmp( bson_iterator_key( &it ), "symbol" ) ); 186 | ASSERT( !strcmp( bson_iterator_string( &it ), "symbol" ) ); 187 | 188 | ASSERT( bson_iterator_more( &it ) ); 189 | ASSERT( bson_iterator_next( &it ) == BSON_SYMBOL ); 190 | ASSERT( bson_iterator_type( &it ) == BSON_SYMBOL ); 191 | ASSERT( !strcmp( bson_iterator_key( &it ), "symbol_n" ) ); 192 | ASSERT( !strcmp( bson_iterator_string( &it ), "symbol" ) ); 193 | 194 | ASSERT( bson_iterator_more( &it ) ); 195 | ASSERT( bson_iterator_next( &it ) == BSON_CODEWSCOPE ); 196 | ASSERT( bson_iterator_type( &it ) == BSON_CODEWSCOPE ); 197 | ASSERT( !strcmp( bson_iterator_key( &it ), "cws" ) ); 198 | ASSERT( !strcmp( bson_iterator_code( &it ), "function(){return i}" ) ); 199 | 200 | { 201 | bson scope; 202 | bson_iterator_code_scope( &it, &scope ); 203 | bson_iterator_init( &it2, &scope ); 204 | 205 | ASSERT( bson_iterator_more( &it2 ) ); 206 | ASSERT( bson_iterator_next( &it2 ) == BSON_INT ); 207 | ASSERT( bson_iterator_type( &it2 ) == BSON_INT ); 208 | ASSERT( !strcmp( bson_iterator_key( &it2 ), "i" ) ); 209 | ASSERT( bson_iterator_int( &it2 ) == 123 ); 210 | 211 | ASSERT( bson_iterator_more( &it2 ) ); 212 | ASSERT( bson_iterator_next( &it2 ) == BSON_EOO ); 213 | ASSERT( bson_iterator_type( &it2 ) == BSON_EOO ); 214 | ASSERT( !bson_iterator_more( &it2 ) ); 215 | } 216 | 217 | ASSERT( bson_iterator_more( &it ) ); 218 | ASSERT( bson_iterator_next( &it ) == BSON_TIMESTAMP ); 219 | ASSERT( bson_iterator_type( &it ) == BSON_TIMESTAMP ); 220 | ASSERT( !strcmp( bson_iterator_key( &it ), "timestamp" ) ); 221 | ts_result = bson_iterator_timestamp( &it ); 222 | ASSERT( ts_result.i == 1 ); 223 | ASSERT( ts_result.t == 2 ); 224 | 225 | ASSERT( bson_iterator_more( &it ) ); 226 | ASSERT( bson_iterator_next( &it ) == BSON_LONG ); 227 | ASSERT( bson_iterator_type( &it ) == BSON_LONG ); 228 | ASSERT( !strcmp( bson_iterator_key( &it ), "l" ) ); 229 | ASSERT( bson_iterator_long( &it ) == 0x1122334455667788 ); 230 | 231 | ASSERT( bson_iterator_more( &it ) ); 232 | ASSERT( bson_iterator_next( &it ) == BSON_EOO ); 233 | ASSERT( bson_iterator_type( &it ) == BSON_EOO ); 234 | ASSERT( !bson_iterator_more( &it ) ); 235 | 236 | bson_destroy( b ); 237 | 238 | return 0; 239 | } 240 | 241 | int test_bson_iterator() { 242 | bson b[1]; 243 | bson_iterator i[1]; 244 | 245 | bson_iterator_init( i, bson_empty( b ) ); 246 | bson_iterator_next( i ); 247 | bson_iterator_type( i ); 248 | 249 | bson_find( i, bson_empty( b ), "foo" ); 250 | 251 | return 0; 252 | } 253 | 254 | int test_bson_size( void ) { 255 | bson bsmall[1]; 256 | 257 | bson_init( bsmall ); 258 | bson_append_int( bsmall, "a", 1 ); 259 | bson_finish( bsmall ); 260 | 261 | ASSERT( bson_size( bsmall ) == 12 ); 262 | 263 | return 0; 264 | } 265 | 266 | int main() { 267 | 268 | test_bson_generic(); 269 | test_bson_iterator(); 270 | test_bson_size(); 271 | 272 | return 0; 273 | } 274 | 275 | -------------------------------------------------------------------------------- /mongo-c-driver-v0.6/test/write_concern_test.c: -------------------------------------------------------------------------------- 1 | /* write_concern_test.c */ 2 | 3 | #include "test.h" 4 | #include "mongo.h" 5 | #include 6 | #include 7 | #include 8 | 9 | /* TODO remove and add mongo_create_collection to the public API. */ 10 | void create_capped_collection( mongo *conn ) { 11 | mongo_cmd_drop_collection( conn, "test", "wc", NULL ); 12 | mongo_create_capped_collection( conn, "test", "wc", 1000000, 0, NULL ); 13 | } 14 | 15 | void test_batch_insert_with_continue( mongo *conn ) { 16 | bson *objs[5]; 17 | bson *objs2[5]; 18 | bson empty; 19 | int i; 20 | 21 | mongo_cmd_drop_collection( conn, TEST_DB, TEST_COL, NULL ); 22 | mongo_create_simple_index( conn, TEST_NS, "n", MONGO_INDEX_UNIQUE, NULL ); 23 | 24 | for( i=0; i<5; i++ ) { 25 | objs[i] = bson_malloc( sizeof( bson ) ); 26 | bson_init( objs[i] ); 27 | bson_append_int( objs[i], "n", i ); 28 | bson_finish( objs[i] ); 29 | } 30 | 31 | ASSERT( mongo_insert_batch( conn, TEST_NS, (const bson **)objs, 5, 32 | NULL, 0 ) == MONGO_OK ); 33 | 34 | ASSERT( mongo_count( conn, TEST_DB, TEST_COL, 35 | bson_empty( &empty ) ) == 5 ); 36 | 37 | /* Add one duplicate value for n. */ 38 | objs2[0] = bson_malloc( sizeof( bson ) ); 39 | bson_init( objs2[0] ); 40 | bson_append_int( objs2[0], "n", 1 ); 41 | bson_finish( objs2[0] ); 42 | 43 | /* Add n for 6 - 9. */ 44 | for( i = 1; i < 5; i++ ) { 45 | objs2[i] = bson_malloc( sizeof( bson ) ); 46 | bson_init( objs2[i] ); 47 | bson_append_int( objs2[i], "n", i + 5 ); 48 | bson_finish( objs2[i] ); 49 | } 50 | 51 | /* Without continue on error, will fail immediately. */ 52 | ASSERT( mongo_insert_batch( conn, TEST_NS, (const bson **)objs2, 5, 53 | NULL, 0 ) == MONGO_OK ); 54 | ASSERT( mongo_count( conn, TEST_DB, TEST_COL, 55 | bson_empty( &empty ) ) == 5 ); 56 | 57 | /* With continue on error, will insert four documents. */ 58 | ASSERT( mongo_insert_batch( conn, TEST_NS, (const bson **)objs2, 5, 59 | NULL, MONGO_CONTINUE_ON_ERROR ) == MONGO_OK ); 60 | ASSERT( mongo_count( conn, TEST_DB, TEST_COL, 61 | bson_empty( &empty ) ) == 9 ); 62 | 63 | for( i=0; i<5; i++ ) { 64 | bson_destroy( objs2[i] ); 65 | bson_free( objs2[i] ); 66 | 67 | bson_destroy( objs[i] ); 68 | bson_free( objs[i] ); 69 | } 70 | } 71 | 72 | /* We can test write concern for update 73 | * and remove by doing operations on a capped collection. */ 74 | void test_update_and_remove( mongo *conn ) { 75 | mongo_write_concern wc[1]; 76 | bson *objs[5]; 77 | bson query[1], update[1]; 78 | bson empty; 79 | int i; 80 | 81 | create_capped_collection( conn ); 82 | 83 | for( i=0; i<5; i++ ) { 84 | objs[i] = bson_malloc( sizeof( bson ) ); 85 | bson_init( objs[i] ); 86 | bson_append_int( objs[i], "n", i ); 87 | bson_finish( objs[i] ); 88 | } 89 | 90 | ASSERT( mongo_insert_batch( conn, "test.wc", (const bson **)objs, 5, 91 | NULL, 0 ) == MONGO_OK ); 92 | 93 | ASSERT( mongo_count( conn, "test", "wc", bson_empty( &empty ) ) == 5 ); 94 | 95 | bson_init( query ); 96 | bson_append_int( query, "n", 2 ); 97 | bson_finish( query ); 98 | 99 | ASSERT( mongo_find_one( conn, "test.wc", query, bson_empty( &empty ), NULL ) == MONGO_OK ); 100 | 101 | bson_init( update ); 102 | bson_append_start_object( update, "$set" ); 103 | bson_append_string( update, "n", "a big long string" ); 104 | bson_append_finish_object( update ); 105 | bson_finish( update ); 106 | 107 | /* Update will appear to succeed with no write concern specified, but doesn't. */ 108 | ASSERT( mongo_find_one( conn, "test.wc", query, bson_empty( &empty ), NULL ) == MONGO_OK ); 109 | ASSERT( mongo_update( conn, "test.wc", query, update, 0, NULL ) == MONGO_OK ); 110 | ASSERT( mongo_find_one( conn, "test.wc", query, bson_empty( &empty ), NULL ) == MONGO_OK ); 111 | 112 | /* Remove will appear to succeed with no write concern specified, but doesn't. */ 113 | ASSERT( mongo_remove( conn, "test.wc", query, NULL ) == MONGO_OK ); 114 | ASSERT( mongo_find_one( conn, "test.wc", query, bson_empty( &empty ), NULL ) == MONGO_OK ); 115 | 116 | mongo_write_concern_init( wc ); 117 | wc->w = 1; 118 | mongo_write_concern_finish( wc ); 119 | 120 | mongo_clear_errors( conn ); 121 | ASSERT( mongo_update( conn, "test.wc", query, update, 0, wc ) == MONGO_ERROR ); 122 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 123 | ASSERT_EQUAL_STRINGS( conn->lasterrstr, "failing update: objects in a capped ns cannot grow" ); 124 | 125 | mongo_clear_errors( conn ); 126 | ASSERT( mongo_remove( conn, "test.wc", query, wc ) == MONGO_ERROR ); 127 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 128 | ASSERT_EQUAL_STRINGS( conn->lasterrstr, "can't remove from a capped collection" ); 129 | 130 | mongo_write_concern_destroy( wc ); 131 | bson_destroy( query ); 132 | bson_destroy( update ); 133 | for( i=0; i<5; i++ ) { 134 | bson_destroy( objs[i] ); 135 | bson_free( objs[i] ); 136 | } 137 | } 138 | 139 | void test_write_concern_input( mongo *conn ) { 140 | mongo_write_concern wc[1], wcbad[1]; 141 | bson b[1]; 142 | 143 | mongo_cmd_drop_collection( conn, TEST_DB, TEST_COL, NULL ); 144 | 145 | bson_init( b ); 146 | bson_append_new_oid( b, "_id" ); 147 | bson_finish( b ); 148 | 149 | mongo_write_concern_init( wc ); 150 | wc->w = 1; 151 | 152 | /* Failure to finish write concern object. */ 153 | ASSERT( mongo_insert( conn, TEST_NS, b, wc ) != MONGO_OK ); 154 | ASSERT( conn->err == MONGO_WRITE_CONCERN_INVALID ); 155 | ASSERT_EQUAL_STRINGS( conn->errstr, 156 | "Must call mongo_write_concern_finish() before using *write_concern." ); 157 | 158 | mongo_write_concern_finish( wc ); 159 | 160 | /* Use a bad write concern. */ 161 | mongo_clear_errors( conn ); 162 | mongo_write_concern_init( wcbad ); 163 | wcbad->w = 2; 164 | mongo_write_concern_finish( wcbad ); 165 | mongo_set_write_concern( conn, wcbad ); 166 | ASSERT( mongo_insert( conn, TEST_NS, b, NULL ) != MONGO_OK ); 167 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 168 | ASSERT_EQUAL_STRINGS( conn->lasterrstr, "norepl" ); 169 | 170 | /* Ensure that supplied write concern overrides default. */ 171 | mongo_clear_errors( conn ); 172 | ASSERT( mongo_insert( conn, TEST_NS, b, wc ) != MONGO_OK ); 173 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 174 | ASSERT_EQUAL_STRINGS( conn->errstr, "See conn->lasterrstr for details." ); 175 | ASSERT_EQUAL_STRINGS( conn->lasterrstr, "E11000 duplicate key error index" ); 176 | ASSERT( conn->lasterrcode == 11000 ); 177 | 178 | conn->write_concern = NULL; 179 | mongo_write_concern_destroy( wc ); 180 | mongo_write_concern_destroy( wcbad ); 181 | } 182 | 183 | void test_insert( mongo *conn ) { 184 | mongo_write_concern wc[1]; 185 | bson b[1], b2[1], b3[1], b4[1], empty[1]; 186 | bson *objs[2]; 187 | 188 | mongo_cmd_drop_collection( conn, TEST_DB, TEST_COL, NULL ); 189 | 190 | mongo_write_concern_init( wc ); 191 | wc->w = 1; 192 | mongo_write_concern_finish( wc ); 193 | 194 | bson_init( b4 ); 195 | bson_append_string( b4, "foo", "bar" ); 196 | bson_finish( b4 ); 197 | 198 | ASSERT( mongo_insert( conn, TEST_NS, b4, wc ) == MONGO_OK ); 199 | 200 | ASSERT( mongo_remove( conn, TEST_NS, bson_empty( empty ), wc ) == MONGO_OK ); 201 | 202 | bson_init( b ); 203 | bson_append_new_oid( b, "_id" ); 204 | bson_finish( b ); 205 | 206 | ASSERT( mongo_insert( conn, TEST_NS, b, NULL ) == MONGO_OK ); 207 | 208 | /* This fails but returns OK because it doesn't use a write concern. */ 209 | ASSERT( mongo_insert( conn, TEST_NS, b, NULL ) == MONGO_OK ); 210 | 211 | ASSERT( mongo_insert( conn, TEST_NS, b, wc ) == MONGO_ERROR ); 212 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 213 | ASSERT_EQUAL_STRINGS( conn->errstr, "See conn->lasterrstr for details." ); 214 | ASSERT_EQUAL_STRINGS( conn->lasterrstr, "E11000 duplicate key error index" ); 215 | ASSERT( conn->lasterrcode == 11000 ); 216 | mongo_clear_errors( conn ); 217 | 218 | /* Still fails but returns OK because it doesn't use a write concern. */ 219 | ASSERT( mongo_insert( conn, TEST_NS, b, NULL ) == MONGO_OK ); 220 | 221 | /* But not when we set a default write concern on the conn. */ 222 | mongo_set_write_concern( conn, wc ); 223 | ASSERT( mongo_insert( conn, TEST_NS, b, NULL ) != MONGO_OK ); 224 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 225 | ASSERT_EQUAL_STRINGS( conn->errstr, "See conn->lasterrstr for details." ); 226 | ASSERT_EQUAL_STRINGS( conn->lasterrstr, "E11000 duplicate key error index" ); 227 | ASSERT( conn->lasterrcode == 11000 ); 228 | 229 | /* Now test batch insert. */ 230 | bson_init( b2 ); 231 | bson_append_new_oid( b2, "_id" ); 232 | bson_finish( b2 ); 233 | 234 | bson_init( b3 ); 235 | bson_append_new_oid( b3, "_id" ); 236 | bson_finish( b3 ); 237 | 238 | objs[0] = b2; 239 | objs[1] = b3; 240 | 241 | /* Insert two new documents by insert_batch. */ 242 | conn->write_concern = NULL; 243 | ASSERT( mongo_count( conn, TEST_DB, TEST_COL, bson_empty( empty ) ) == 1 ); 244 | ASSERT( mongo_insert_batch( conn, TEST_NS, (const bson **)objs, 2, NULL, 0 ) == MONGO_OK ); 245 | ASSERT( mongo_count( conn, TEST_DB, TEST_COL, bson_empty( empty ) ) == 3 ); 246 | 247 | /* This should definitely fail if we try again with write concern. */ 248 | mongo_clear_errors( conn ); 249 | ASSERT( mongo_insert_batch( conn, TEST_NS, (const bson **)objs, 2, wc, 0 ) == MONGO_ERROR ); 250 | ASSERT( conn->err == MONGO_WRITE_ERROR ); 251 | ASSERT_EQUAL_STRINGS( conn->errstr, "See conn->lasterrstr for details." ); 252 | ASSERT_EQUAL_STRINGS( conn->lasterrstr, "E11000 duplicate key error index" ); 253 | ASSERT( conn->lasterrcode == 11000 ); 254 | 255 | /* But it will succeed without the write concern set. */ 256 | ASSERT( mongo_insert_batch( conn, TEST_NS, (const bson **)objs, 2, NULL, 0 ) == MONGO_OK ); 257 | 258 | bson_destroy( b ); 259 | bson_destroy( b2 ); 260 | bson_destroy( b3 ); 261 | mongo_write_concern_destroy( wc ); 262 | } 263 | 264 | int main() { 265 | mongo conn[1]; 266 | char version[10]; 267 | 268 | INIT_SOCKETS_FOR_WINDOWS; 269 | 270 | if( mongo_connect( conn, TEST_SERVER, 27017 ) != MONGO_OK ) { 271 | printf( "failed to connect\n" ); 272 | exit( 1 ); 273 | } 274 | 275 | test_insert( conn ); 276 | if( mongo_get_server_version( version ) != -1 && version[0] != '1' ) { 277 | test_write_concern_input( conn ); 278 | test_update_and_remove( conn ); 279 | test_batch_insert_with_continue( conn ); 280 | } 281 | 282 | mongo_destroy( conn ); 283 | return 0; 284 | } 285 | --------------------------------------------------------------------------------