bson_ext 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -4
- data/ext/cbson/{buffer.c → bson_buffer.c} +30 -14
- data/ext/cbson/{buffer.h → bson_buffer.h} +16 -12
- data/ext/cbson/cbson.c +61 -56
- data/ext/cbson/version.h +1 -1
- data/ext/cmongo/c-driver/src/bson.c +699 -0
- data/ext/cmongo/c-driver/src/bson.h +229 -0
- data/ext/cmongo/c-driver/src/gridfs.c +799 -0
- data/ext/cmongo/c-driver/src/gridfs.h +278 -0
- data/ext/cmongo/c-driver/src/md5.c +381 -0
- data/ext/cmongo/c-driver/src/md5.h +91 -0
- data/ext/cmongo/c-driver/src/mongo.c +1020 -0
- data/ext/cmongo/c-driver/src/mongo.h +260 -0
- data/ext/cmongo/c-driver/src/mongo_except.h +143 -0
- data/ext/cmongo/c-driver/src/numbers.c +127 -0
- data/ext/cmongo/c-driver/src/platform_hacks.h +93 -0
- data/ext/cmongo/c-driver/test/all_types.c +223 -0
- data/ext/cmongo/c-driver/test/auth.c +28 -0
- data/ext/cmongo/c-driver/test/benchmark.c +434 -0
- data/ext/cmongo/c-driver/test/count_delete.c +64 -0
- data/ext/cmongo/c-driver/test/endian_swap.c +31 -0
- data/ext/cmongo/c-driver/test/errors.c +71 -0
- data/ext/cmongo/c-driver/test/examples.c +75 -0
- data/ext/cmongo/c-driver/test/gridfs.c +217 -0
- data/ext/cmongo/c-driver/test/json.c +169 -0
- data/ext/cmongo/c-driver/test/pair.c +41 -0
- data/ext/cmongo/c-driver/test/replica_set.c +81 -0
- data/ext/cmongo/c-driver/test/resize.c +35 -0
- data/ext/cmongo/c-driver/test/simple.c +110 -0
- data/ext/cmongo/c-driver/test/sizes.c +22 -0
- data/ext/cmongo/c-driver/test/test.h +19 -0
- data/ext/cmongo/c-driver/test/update.c +107 -0
- metadata +61 -29
@@ -0,0 +1,64 @@
|
|
1
|
+
/* count_delete.c */
|
2
|
+
|
3
|
+
#include "test.h"
|
4
|
+
#include "mongo.h"
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include <stdlib.h>
|
8
|
+
|
9
|
+
int main(){
|
10
|
+
mongo_connection conn[1];
|
11
|
+
bson_buffer bb;
|
12
|
+
bson b;
|
13
|
+
int i;
|
14
|
+
|
15
|
+
const char * db = "test";
|
16
|
+
const char * col = "c.simple";
|
17
|
+
const char * ns = "test.c.simple";
|
18
|
+
|
19
|
+
INIT_SOCKETS_FOR_WINDOWS;
|
20
|
+
|
21
|
+
if (mongo_connect( conn , TEST_SERVER , 27017 )){
|
22
|
+
printf("failed to connect\n");
|
23
|
+
exit(1);
|
24
|
+
}
|
25
|
+
|
26
|
+
/* if the collection doesn't exist dropping it will fail */
|
27
|
+
if (!mongo_cmd_drop_collection(conn, "test", col, NULL)
|
28
|
+
&& mongo_count(conn, db, col, NULL) != 0){
|
29
|
+
printf("failed to drop collection\n");
|
30
|
+
exit(1);
|
31
|
+
}
|
32
|
+
|
33
|
+
for(i=0; i< 5; i++){
|
34
|
+
bson_buffer_init( & bb );
|
35
|
+
|
36
|
+
bson_append_new_oid( &bb, "_id" );
|
37
|
+
bson_append_int( &bb , "a" , i+1 ); /* 1 to 5 */
|
38
|
+
bson_from_buffer(&b, &bb);
|
39
|
+
|
40
|
+
mongo_insert( conn , ns , &b );
|
41
|
+
bson_destroy(&b);
|
42
|
+
}
|
43
|
+
|
44
|
+
/* query: {a: {$gt: 3}} */
|
45
|
+
bson_buffer_init( & bb );
|
46
|
+
{
|
47
|
+
bson_buffer * sub = bson_append_start_object(&bb, "a");
|
48
|
+
bson_append_int(sub, "$gt", 3);
|
49
|
+
bson_append_finish_object(sub);
|
50
|
+
}
|
51
|
+
bson_from_buffer(&b, &bb);
|
52
|
+
|
53
|
+
ASSERT(mongo_count(conn, db, col, NULL) == 5);
|
54
|
+
ASSERT(mongo_count(conn, db, col, &b) == 2);
|
55
|
+
|
56
|
+
mongo_remove(conn, ns, &b);
|
57
|
+
|
58
|
+
ASSERT(mongo_count(conn, db, col, NULL) == 3);
|
59
|
+
ASSERT(mongo_count(conn, db, col, &b) == 0);
|
60
|
+
|
61
|
+
mongo_cmd_drop_db(conn, db);
|
62
|
+
mongo_destroy(conn);
|
63
|
+
return 0;
|
64
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/* endian_swap.c */
|
2
|
+
|
3
|
+
#include "test.h"
|
4
|
+
#include "platform_hacks.h"
|
5
|
+
#include <stdio.h>
|
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
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#include "test.h"
|
2
|
+
#include "mongo.h"
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
|
7
|
+
static mongo_connection conn[1];
|
8
|
+
static const char* db = "test";
|
9
|
+
static const char* ns = "test.c.error";
|
10
|
+
|
11
|
+
int main(){
|
12
|
+
bson obj;
|
13
|
+
|
14
|
+
INIT_SOCKETS_FOR_WINDOWS;
|
15
|
+
|
16
|
+
if (mongo_connect( conn , TEST_SERVER, 27017 )){
|
17
|
+
printf("failed to connect\n");
|
18
|
+
exit(1);
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
/*********************/
|
23
|
+
ASSERT(!mongo_cmd_get_prev_error(conn, db, NULL));
|
24
|
+
ASSERT(!mongo_cmd_get_last_error(conn, db, NULL));
|
25
|
+
|
26
|
+
ASSERT(!mongo_cmd_get_prev_error(conn, db, &obj));
|
27
|
+
bson_destroy(&obj);
|
28
|
+
|
29
|
+
ASSERT(!mongo_cmd_get_last_error(conn, db, &obj));
|
30
|
+
bson_destroy(&obj);
|
31
|
+
|
32
|
+
/*********************/
|
33
|
+
mongo_simple_int_command(conn, db, "forceerror", 1, NULL);
|
34
|
+
|
35
|
+
ASSERT(mongo_cmd_get_prev_error(conn, db, NULL));
|
36
|
+
ASSERT(mongo_cmd_get_last_error(conn, db, NULL));
|
37
|
+
|
38
|
+
ASSERT(mongo_cmd_get_prev_error(conn, db, &obj));
|
39
|
+
bson_destroy(&obj);
|
40
|
+
|
41
|
+
ASSERT(mongo_cmd_get_last_error(conn, db, &obj));
|
42
|
+
bson_destroy(&obj);
|
43
|
+
|
44
|
+
/* should clear lasterror but not preverror */
|
45
|
+
mongo_find_one(conn, ns, bson_empty(&obj), bson_empty(&obj), NULL);
|
46
|
+
|
47
|
+
ASSERT(mongo_cmd_get_prev_error(conn, db, NULL));
|
48
|
+
ASSERT(!mongo_cmd_get_last_error(conn, db, NULL));
|
49
|
+
|
50
|
+
ASSERT(mongo_cmd_get_prev_error(conn, db, &obj));
|
51
|
+
bson_destroy(&obj);
|
52
|
+
|
53
|
+
ASSERT(!mongo_cmd_get_last_error(conn, db, &obj));
|
54
|
+
bson_destroy(&obj);
|
55
|
+
|
56
|
+
/*********************/
|
57
|
+
mongo_cmd_reset_error(conn, db);
|
58
|
+
|
59
|
+
ASSERT(!mongo_cmd_get_prev_error(conn, db, NULL));
|
60
|
+
ASSERT(!mongo_cmd_get_last_error(conn, db, NULL));
|
61
|
+
|
62
|
+
ASSERT(!mongo_cmd_get_prev_error(conn, db, &obj));
|
63
|
+
bson_destroy(&obj);
|
64
|
+
|
65
|
+
ASSERT(!mongo_cmd_get_last_error(conn, db, &obj));
|
66
|
+
bson_destroy(&obj);
|
67
|
+
|
68
|
+
mongo_cmd_drop_db(conn, db);
|
69
|
+
mongo_destroy(conn);
|
70
|
+
return 0;
|
71
|
+
}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#include "test.h"
|
2
|
+
#include "bson.h"
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <string.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
|
7
|
+
int main(){
|
8
|
+
bson_buffer bb;
|
9
|
+
bson b, sub;
|
10
|
+
bson_iterator it;
|
11
|
+
|
12
|
+
/* Create a rich document like this one:
|
13
|
+
*
|
14
|
+
* { _id: ObjectId("4d95ea712b752328eb2fc2cc"),
|
15
|
+
* user_id: ObjectId("4d95ea712b752328eb2fc2cd"),
|
16
|
+
*
|
17
|
+
* items: [
|
18
|
+
* { sku: "col-123",
|
19
|
+
* name: "John Coltrane: Impressions",
|
20
|
+
* price: 1099,
|
21
|
+
* },
|
22
|
+
*
|
23
|
+
* { sku: "young-456",
|
24
|
+
* name: "Larry Young: Unity",
|
25
|
+
* price: 1199
|
26
|
+
* }
|
27
|
+
* ],
|
28
|
+
*
|
29
|
+
* address: {
|
30
|
+
* street: "59 18th St.",
|
31
|
+
* zip: 10010
|
32
|
+
* },
|
33
|
+
*
|
34
|
+
* total: 2298
|
35
|
+
* }
|
36
|
+
*/
|
37
|
+
bson_buffer_init( &bb );
|
38
|
+
bson_append_new_oid( &bb, "_id" );
|
39
|
+
bson_append_new_oid( &bb, "user_id" );
|
40
|
+
|
41
|
+
bson_append_start_array( &bb, "items" );
|
42
|
+
bson_append_start_object( &bb, "0" );
|
43
|
+
bson_append_string( &bb, "name", "John Coltrane: Impressions" );
|
44
|
+
bson_append_int( &bb, "price", 1099 );
|
45
|
+
bson_append_finish_object( &bb );
|
46
|
+
|
47
|
+
bson_append_start_object( &bb, "1" );
|
48
|
+
bson_append_string( &bb, "name", "Larry Young: Unity" );
|
49
|
+
bson_append_int( &bb, "price", 1199 );
|
50
|
+
bson_append_finish_object( &bb );
|
51
|
+
bson_append_finish_object( &bb );
|
52
|
+
|
53
|
+
bson_append_start_object( &bb, "address" );
|
54
|
+
bson_append_string( &bb, "street", "59 18th St." );
|
55
|
+
bson_append_int( &bb, "zip", 10010 );
|
56
|
+
bson_append_finish_object( &bb );
|
57
|
+
|
58
|
+
bson_append_int( &bb, "total", 2298 );
|
59
|
+
|
60
|
+
/* Convert from a buffer to a raw BSON object that
|
61
|
+
* can be sent to the server:
|
62
|
+
*/
|
63
|
+
bson_from_buffer( &b, &bb );
|
64
|
+
|
65
|
+
/* Advance to the 'items' array */
|
66
|
+
bson_find( &it, &b, "items" );
|
67
|
+
|
68
|
+
/* Get the subobject representing items */
|
69
|
+
bson_iterator_subobject( &it, &sub );
|
70
|
+
|
71
|
+
/* Now iterate that object */
|
72
|
+
bson_print( &sub );
|
73
|
+
|
74
|
+
return 0;
|
75
|
+
}
|
@@ -0,0 +1,217 @@
|
|
1
|
+
#include "test.h"
|
2
|
+
#include "md5.h"
|
3
|
+
#include "mongo.h"
|
4
|
+
#include "gridfs.h"
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include <stdio.h>
|
8
|
+
|
9
|
+
#define LARGE 3*1024*1024
|
10
|
+
#define UPPER 2000*1024
|
11
|
+
#define LOWER 1024*128
|
12
|
+
#define DELTA 1024*128
|
13
|
+
|
14
|
+
void fill_buffer_randomly(char * data, int64_t length)
|
15
|
+
{
|
16
|
+
int64_t i;
|
17
|
+
int random;
|
18
|
+
char * letters = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
19
|
+
int nletters = strlen(letters)+1;
|
20
|
+
|
21
|
+
for (i = 0; i < length; i++) {
|
22
|
+
random = rand() % nletters;
|
23
|
+
*(data + i) = letters[random];
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
static void digest2hex(mongo_md5_byte_t digest[16], char hex_digest[33]){
|
28
|
+
static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
29
|
+
int i;
|
30
|
+
for (i=0; i<16; i++){
|
31
|
+
hex_digest[2*i] = hex[(digest[i] & 0xf0) >> 4];
|
32
|
+
hex_digest[2*i + 1] = hex[ digest[i] & 0x0f ];
|
33
|
+
}
|
34
|
+
hex_digest[32] = '\0';
|
35
|
+
}
|
36
|
+
|
37
|
+
void test_gridfile(gridfs *gfs, char *data_before, int64_t length, char *filename, char *content_type) {
|
38
|
+
gridfile gfile[1];
|
39
|
+
char data_after[LARGE];
|
40
|
+
FILE * fd;
|
41
|
+
mongo_md5_state_t pms[1];
|
42
|
+
mongo_md5_byte_t digest[16];
|
43
|
+
char hex_digest[33];
|
44
|
+
|
45
|
+
gridfs_find_filename(gfs, filename, gfile);
|
46
|
+
ASSERT(gridfile_exists(gfile));
|
47
|
+
|
48
|
+
fd = fopen("output", "w+");
|
49
|
+
gridfile_write_file(gfile, fd);
|
50
|
+
fseek(fd, 0, SEEK_SET);
|
51
|
+
ASSERT(fread(data_after, length, sizeof(char), fd));
|
52
|
+
fclose(fd);
|
53
|
+
ASSERT( strncmp(data_before, data_after, length) == 0 );
|
54
|
+
|
55
|
+
gridfile_read( gfile, length, data_after );
|
56
|
+
ASSERT( strncmp(data_before, data_after, length) == 0 );
|
57
|
+
|
58
|
+
ASSERT( strcmp( gridfile_get_filename( gfile ), filename ) == 0 );
|
59
|
+
|
60
|
+
ASSERT( gridfile_get_contentlength( gfile ) == length );
|
61
|
+
|
62
|
+
ASSERT( gridfile_get_chunksize( gfile ) == DEFAULT_CHUNK_SIZE );
|
63
|
+
|
64
|
+
ASSERT( strcmp( gridfile_get_contenttype( gfile ), content_type ) == 0) ;
|
65
|
+
|
66
|
+
mongo_md5_init(pms);
|
67
|
+
mongo_md5_append(pms, (const mongo_md5_byte_t *)data_before, (int)length);
|
68
|
+
mongo_md5_finish(pms, digest);
|
69
|
+
digest2hex(digest, hex_digest);
|
70
|
+
ASSERT( strcmp( gridfile_get_md5( gfile ), hex_digest ) == 0 );
|
71
|
+
|
72
|
+
gridfile_destroy(gfile);
|
73
|
+
gridfs_remove_filename(gfs, filename);
|
74
|
+
}
|
75
|
+
|
76
|
+
void test_basic() {
|
77
|
+
mongo_connection conn[1];
|
78
|
+
gridfs gfs[1];
|
79
|
+
char data_before[UPPER];
|
80
|
+
int64_t i;
|
81
|
+
FILE *fd;
|
82
|
+
|
83
|
+
srand(time(NULL));
|
84
|
+
|
85
|
+
INIT_SOCKETS_FOR_WINDOWS;
|
86
|
+
|
87
|
+
if (mongo_connect( conn, TEST_SERVER, 27017 )){
|
88
|
+
printf("failed to connect 2\n");
|
89
|
+
exit(1);
|
90
|
+
}
|
91
|
+
|
92
|
+
gridfs_init(conn, "test", "fs", gfs);
|
93
|
+
|
94
|
+
for (i = LOWER; i <= UPPER; i+=DELTA) {
|
95
|
+
fill_buffer_randomly(data_before, i);
|
96
|
+
|
97
|
+
/* Input from buffer */
|
98
|
+
gridfs_store_buffer(gfs, data_before, i, "input-buffer", "text/html");
|
99
|
+
test_gridfile(gfs, data_before, i, "input-buffer", "text/html");
|
100
|
+
|
101
|
+
/* Input from file */
|
102
|
+
fd = fopen("input-file", "w");
|
103
|
+
fwrite(data_before, sizeof(char), i, fd);
|
104
|
+
fclose(fd);
|
105
|
+
gridfs_store_file(gfs, "input-file", "input-file", "text/html");
|
106
|
+
test_gridfile(gfs, data_before, i, "input-file", "text/html");
|
107
|
+
}
|
108
|
+
|
109
|
+
gridfs_destroy(gfs);
|
110
|
+
mongo_disconnect(conn);
|
111
|
+
mongo_destroy(conn);
|
112
|
+
}
|
113
|
+
|
114
|
+
void test_streaming() {
|
115
|
+
mongo_connection conn[1];
|
116
|
+
gridfs gfs[1];
|
117
|
+
gridfile gfile[1];
|
118
|
+
char buf[LARGE];
|
119
|
+
char small[LOWER];
|
120
|
+
int n;
|
121
|
+
|
122
|
+
srand(time(NULL));
|
123
|
+
|
124
|
+
INIT_SOCKETS_FOR_WINDOWS;
|
125
|
+
|
126
|
+
if (mongo_connect( conn , TEST_SERVER, 27017 )){
|
127
|
+
printf("failed to connect 3\n");
|
128
|
+
exit(1);
|
129
|
+
}
|
130
|
+
|
131
|
+
fill_buffer_randomly(small, (int64_t)LOWER);
|
132
|
+
fill_buffer_randomly(buf, (int64_t)LARGE);
|
133
|
+
|
134
|
+
gridfs_init(conn, "test", "fs", gfs);
|
135
|
+
|
136
|
+
gridfs_store_buffer(gfs, small, LOWER, "small", "text/html");
|
137
|
+
test_gridfile(gfs, small, LOWER, "small", "text/html");
|
138
|
+
gridfs_destroy(gfs);
|
139
|
+
|
140
|
+
gridfs_init(conn, "test", "fs", gfs);
|
141
|
+
gridfile_writer_init(gfile, gfs, "large", "text/html");
|
142
|
+
for(n=0; n < (LARGE / 1024); n++) {
|
143
|
+
gridfile_write_buffer(gfile, buf + (n * 1024), 1024);
|
144
|
+
}
|
145
|
+
gridfile_writer_done( gfile );
|
146
|
+
test_gridfile(gfs, buf, LARGE, "large", "text/html");
|
147
|
+
|
148
|
+
gridfs_destroy(gfs);
|
149
|
+
mongo_destroy(conn);
|
150
|
+
}
|
151
|
+
|
152
|
+
void test_large() {
|
153
|
+
mongo_connection conn[1];
|
154
|
+
gridfs gfs[1];
|
155
|
+
gridfile gfile[1];
|
156
|
+
FILE *fd;
|
157
|
+
int i, n;
|
158
|
+
char buffer[LARGE];
|
159
|
+
int64_t filesize = (int64_t)1024 * (int64_t)LARGE;
|
160
|
+
|
161
|
+
srand(time(NULL));
|
162
|
+
|
163
|
+
INIT_SOCKETS_FOR_WINDOWS;
|
164
|
+
|
165
|
+
if (mongo_connect( conn, TEST_SERVER, 27017 )){
|
166
|
+
printf("failed to connect 1\n");
|
167
|
+
exit(1);
|
168
|
+
}
|
169
|
+
|
170
|
+
gridfs_init(conn, "test", "fs", gfs);
|
171
|
+
|
172
|
+
/* Create a very large file */
|
173
|
+
fill_buffer_randomly(buffer, (int64_t)LARGE);
|
174
|
+
fd = fopen("bigfile", "w");
|
175
|
+
for(i=0; i<1024; i++) {
|
176
|
+
fwrite(buffer, 1, LARGE, fd);
|
177
|
+
}
|
178
|
+
fclose(fd);
|
179
|
+
|
180
|
+
/* Now read the file into GridFS */
|
181
|
+
gridfs_store_file(gfs, "bigfile", "bigfile", "text/html");
|
182
|
+
|
183
|
+
gridfs_find_filename(gfs, "bigfile", gfile);
|
184
|
+
|
185
|
+
ASSERT( strcmp( gridfile_get_filename( gfile ), "bigfile" ) == 0 );
|
186
|
+
ASSERT( gridfile_get_contentlength( gfile ) == filesize );
|
187
|
+
|
188
|
+
/* Read the file using the streaming interface */
|
189
|
+
gridfile_writer_init( gfile, gfs, "bigfile-stream", "text/html");
|
190
|
+
|
191
|
+
fd = fopen("bigfile", "r");
|
192
|
+
|
193
|
+
while((n = fread(buffer, 1, 1024, fd)) != 0) {
|
194
|
+
gridfile_write_buffer(gfile, buffer, n);
|
195
|
+
}
|
196
|
+
gridfile_writer_done( gfile );
|
197
|
+
|
198
|
+
gridfs_find_filename(gfs, "bigfile-stream", gfile);
|
199
|
+
|
200
|
+
ASSERT( strcmp( gridfile_get_filename( gfile ), "bigfile-stream" ) == 0 );
|
201
|
+
ASSERT( gridfile_get_contentlength( gfile ) == filesize );
|
202
|
+
|
203
|
+
gridfs_destroy(gfs);
|
204
|
+
mongo_disconnect(conn);
|
205
|
+
mongo_destroy(conn);
|
206
|
+
}
|
207
|
+
|
208
|
+
int main(void) {
|
209
|
+
test_basic();
|
210
|
+
test_streaming();
|
211
|
+
|
212
|
+
/* Normally not necessary to run test_large(), as it
|
213
|
+
* deals with very large (3GB) files and is therefore slow.
|
214
|
+
* test_large();
|
215
|
+
*/
|
216
|
+
return 0;
|
217
|
+
}
|