Skip to content

Commit af80d64

Browse files
committed
PHPC-42: Implement root level (full document) ODM style serialization
1 parent 51ac675 commit af80d64

File tree

9 files changed

+321
-161
lines changed

9 files changed

+321
-161
lines changed

php_phongo.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,6 @@ void php_phongo_result_free(php_phongo_result_t *result)
11691169
/* {{{ Iterator */
11701170
typedef struct {
11711171
zend_object_iterator iterator;
1172-
zval *current;
11731172
mongoc_cursor_t *cursor;
11741173
bson_t *firstBatch;
11751174
bson_iter_t first_batch_iter;
@@ -1182,8 +1181,9 @@ static void phongo_cursor_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ *
11821181
{
11831182
phongo_cursor_it *cursor_it = (phongo_cursor_it *)iter;
11841183

1185-
if (cursor_it->current) {
1186-
zval_ptr_dtor(&cursor_it->current);
1184+
if (cursor_it->visitor_data.zchild) {
1185+
zval_ptr_dtor(&cursor_it->visitor_data.zchild);
1186+
cursor_it->visitor_data.zchild = NULL;
11871187
}
11881188

11891189
zval_ptr_dtor((zval**)&cursor_it->iterator.data);
@@ -1192,22 +1192,22 @@ static void phongo_cursor_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ *
11921192

11931193
static int phongo_cursor_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
11941194
{
1195-
return ((phongo_cursor_it *)iter)->current ? SUCCESS : FAILURE;
1195+
return ((phongo_cursor_it *)iter)->visitor_data.zchild ? SUCCESS : FAILURE;
11961196
} /* }}} */
11971197

11981198
static void phongo_cursor_it_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
11991199
{
1200-
*data = &((phongo_cursor_it *)iter)->current;
1200+
*data = &((phongo_cursor_it *)iter)->visitor_data.zchild;
12011201
} /* }}} */
12021202

12031203
static void phongo_cursor_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
12041204
{
12051205
phongo_cursor_it *cursor_it = (phongo_cursor_it *)iter;
12061206
const bson_t *doc;
12071207

1208-
if (cursor_it->current) {
1209-
zval_ptr_dtor(&cursor_it->current);
1210-
cursor_it->current = NULL;
1208+
if (cursor_it->visitor_data.zchild) {
1209+
zval_ptr_dtor(&cursor_it->visitor_data.zchild);
1210+
cursor_it->visitor_data.zchild = NULL;
12111211
}
12121212

12131213
if (bson_iter_next(&cursor_it->first_batch_iter)) {
@@ -1217,18 +1217,16 @@ static void phongo_cursor_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
12171217

12181218
bson_iter_document(&cursor_it->first_batch_iter, &data_len, &data);
12191219

1220-
MAKE_STD_ZVAL(cursor_it->current);
1221-
cursor_it->visitor_data.zchild = cursor_it->current;
1220+
MAKE_STD_ZVAL(cursor_it->visitor_data.zchild);
12221221
bson_to_zval(data, data_len, &cursor_it->visitor_data);
12231222
return;
12241223
}
12251224
}
12261225
if (mongoc_cursor_next(cursor_it->cursor, &doc)) {
1227-
MAKE_STD_ZVAL(cursor_it->current);
1228-
cursor_it->visitor_data.zchild = cursor_it->current;
1226+
MAKE_STD_ZVAL(cursor_it->visitor_data.zchild);
12291227
bson_to_zval(bson_get_data(doc), doc->len, &cursor_it->visitor_data);
12301228
} else {
1231-
cursor_it->current = NULL;
1229+
cursor_it->visitor_data.zchild = NULL;
12321230
}
12331231

12341232
} /* }}} */
@@ -1237,6 +1235,11 @@ static void phongo_cursor_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{
12371235
{
12381236
phongo_cursor_it *cursor_it = (phongo_cursor_it *)iter;
12391237

1238+
if (cursor_it->visitor_data.zchild) {
1239+
zval_ptr_dtor(&cursor_it->visitor_data.zchild);
1240+
cursor_it->visitor_data.zchild = NULL;
1241+
}
1242+
12401243
/* firstBatch is empty when the query simply didn't return any results */
12411244
if (cursor_it->firstBatch) {
12421245
if (cursor_it->is_command_cursor) {
@@ -1249,14 +1252,12 @@ static void phongo_cursor_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{
12491252
uint32_t data_len = 0;
12501253

12511254
bson_iter_document(&cursor_it->first_batch_iter, &data_len, &data);
1252-
MAKE_STD_ZVAL(cursor_it->current);
1253-
cursor_it->visitor_data.zchild = cursor_it->current;
1255+
MAKE_STD_ZVAL(cursor_it->visitor_data.zchild);
12541256
bson_to_zval(data, data_len, &cursor_it->visitor_data);
12551257
}
12561258
}
12571259
} else {
1258-
MAKE_STD_ZVAL(cursor_it->current);
1259-
cursor_it->visitor_data.zchild = cursor_it->current;
1260+
MAKE_STD_ZVAL(cursor_it->visitor_data.zchild);
12601261
bson_to_zval(bson_get_data(cursor_it->firstBatch), cursor_it->firstBatch->len, &cursor_it->visitor_data);
12611262
}
12621263
}
@@ -1332,6 +1333,10 @@ zend_object_iterator *phongo_result_get_iterator(zend_class_entry *ce, zval *obj
13321333

13331334
cursor_it = ecalloc(1, sizeof(phongo_cursor_it));
13341335

1336+
if (cursor_it->visitor_data.zchild) {
1337+
zval_ptr_dtor(&cursor_it->visitor_data.zchild);
1338+
cursor_it->visitor_data.zchild = NULL;
1339+
}
13351340
Z_ADDREF_P(object);
13361341
cursor_it->iterator.data = (void*)object;
13371342
cursor_it->iterator.funcs = &phongo_cursor_it_funcs;

src/MongoDB/CommandResult.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,9 @@ PHP_METHOD(CommandResult, getResponseDocument)
152152
if (intern->result.firstBatch) {
153153
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
154154

155-
state.zchild = return_value;
155+
MAKE_STD_ZVAL(state.zchild);
156156
bson_to_zval(bson_get_data(intern->result.firstBatch), intern->result.firstBatch->len, &state);
157+
RETURN_ZVAL(state.zchild, 0, 1);
157158
}
158159
}
159160
/* }}} */

src/bson.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,18 @@ PHONGO_API void zval_to_bson(zval *data, phongo_bson_flags_t flags, bson_t *bson
735735

736736
switch(Z_TYPE_P(data)) {
737737
case IS_OBJECT:
738+
if (instanceof_function(Z_OBJCE_P(data), php_phongo_persistable_ce TSRMLS_CC)) {
739+
zval *retval;
740+
741+
bson_append_binary(bson, "__", -1, 0x80, (const uint8_t *)Z_OBJCE_P(data)->name, strlen(Z_OBJCE_P(data)->name));
742+
743+
zend_call_method_with_0_params(&data, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &retval);
744+
if(retval) {
745+
ZVAL_ZVAL(data, retval, 0, 1);
746+
convert_to_array(data);
747+
}
748+
}
749+
738750
case IS_ARRAY:
739751
ht_data = HASH_OF(data);
740752
break;
@@ -829,6 +841,15 @@ int bson_to_zval(const unsigned char *data, int data_len, php_phongo_bson_state
829841

830842
array_init(state->zchild);
831843
bson_iter_visit_all(&iter, &php_bson_visitors, state);
844+
if (state->map.array || state->odm) {
845+
zval *obj = NULL;
846+
847+
MAKE_STD_ZVAL(obj);
848+
object_init_ex(obj, state->odm ? state->odm : state->map.array);
849+
zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, state->zchild);
850+
zval_dtor(state->zchild);
851+
ZVAL_ZVAL(state->zchild, obj, 1, 1);
852+
}
832853
} while ((b = bson_reader_read(reader, &eof)));
833854

834855
bson_reader_destroy(reader);
@@ -911,10 +932,11 @@ PHP_FUNCTION(toArray)
911932

912933
php_phongo_bson_typemap_to_state(typemap, &state.map TSRMLS_CC);
913934

914-
state.zchild = return_value;
935+
MAKE_STD_ZVAL(state.zchild);
915936
if (!bson_to_zval((const unsigned char *)data, data_len, &state)) {
916937
RETURN_NULL();
917938
}
939+
RETURN_ZVAL(state.zchild, 0, 1);
918940
}
919941
/* }}} */
920942

tests/bson/bson-decode-002.phpt

Lines changed: 72 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,82 +31,100 @@ foreach($tests as $n => $test) {
3131
<?php exit(0); ?>
3232
--EXPECTF--
3333
Test#%d { "0" : { "hello" : "world" } }
34-
array(1) {
35-
[0]=>
36-
object(MyArrayObject)#%d (1) {
37-
[%s]=>
38-
array(1) {
39-
["hello"]=>
40-
string(5) "world"
34+
object(MyArrayObject)#%d (1) {
35+
[%s]=>
36+
array(1) {
37+
[0]=>
38+
object(MyArrayObject)#%d (1) {
39+
[%s]=>
40+
array(1) {
41+
["hello"]=>
42+
string(5) "world"
43+
}
4144
}
4245
}
4346
}
4447
Test#%d { "0" : { "hello" : "world" } }
45-
array(1) {
46-
[0]=>
47-
object(MyArrayObject)#%d (1) {
48-
[%s]=>
49-
array(1) {
50-
["hello"]=>
51-
string(5) "world"
48+
object(MyArrayObject)#%d (1) {
49+
[%s]=>
50+
array(1) {
51+
[0]=>
52+
object(MyArrayObject)#%d (1) {
53+
[%s]=>
54+
array(1) {
55+
["hello"]=>
56+
string(5) "world"
57+
}
5258
}
5359
}
5460
}
5561
Test#%d { "my" : { "hello" : "world" } }
56-
array(1) {
57-
["my"]=>
58-
object(MyArrayObject)#%d (1) {
59-
[%s]=>
60-
array(1) {
61-
["hello"]=>
62-
string(5) "world"
62+
object(MyArrayObject)#%d (1) {
63+
[%s]=>
64+
array(1) {
65+
["my"]=>
66+
object(MyArrayObject)#%d (1) {
67+
[%s]=>
68+
array(1) {
69+
["hello"]=>
70+
string(5) "world"
71+
}
6372
}
6473
}
6574
}
6675
Test#%d { "my" : { "hello" : "world" } }
67-
array(1) {
68-
["my"]=>
69-
object(MyArrayObject)#%d (1) {
70-
[%s]=>
71-
array(1) {
72-
["hello"]=>
73-
string(5) "world"
76+
object(MyArrayObject)#%d (1) {
77+
[%s]=>
78+
array(1) {
79+
["my"]=>
80+
object(MyArrayObject)#%d (1) {
81+
[%s]=>
82+
array(1) {
83+
["hello"]=>
84+
string(5) "world"
85+
}
7486
}
7587
}
7688
}
7789
Test#%d { "my" : [ [ "hello", "world" ] ] }
78-
array(1) {
79-
["my"]=>
80-
object(MyArrayObject)#%d (1) {
81-
[%s]=>
82-
array(1) {
83-
[0]=>
84-
object(MyArrayObject)#%d (1) {
85-
[%s]=>
86-
array(2) {
87-
[0]=>
88-
string(5) "hello"
89-
[1]=>
90-
string(5) "world"
90+
object(MyArrayObject)#%d (1) {
91+
[%s]=>
92+
array(1) {
93+
["my"]=>
94+
object(MyArrayObject)#%d (1) {
95+
[%s]=>
96+
array(1) {
97+
[0]=>
98+
object(MyArrayObject)#%d (1) {
99+
[%s]=>
100+
array(2) {
101+
[0]=>
102+
string(5) "hello"
103+
[1]=>
104+
string(5) "world"
105+
}
91106
}
92107
}
93108
}
94109
}
95110
}
96111
Test#%d { "my" : { "0" : [ "hello", "world" ] } }
97-
array(1) {
98-
["my"]=>
99-
object(MyArrayObject)#%d (1) {
100-
[%s]=>
101-
array(1) {
102-
[0]=>
103-
object(MyArrayObject)#%d (1) {
104-
[%s]=>
105-
array(2) {
106-
[0]=>
107-
string(5) "hello"
108-
[1]=>
109-
string(5) "world"
112+
object(MyArrayObject)#%d (1) {
113+
[%s]=>
114+
array(1) {
115+
["my"]=>
116+
object(MyArrayObject)#%d (1) {
117+
[%s]=>
118+
array(1) {
119+
[0]=>
120+
object(MyArrayObject)#%d (1) {
121+
[%s]=>
122+
array(2) {
123+
[0]=>
124+
string(5) "hello"
125+
[1]=>
126+
string(5) "world"
127+
}
110128
}
111129
}
112130
}

tests/bson/bson-encode-002.phpt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ foreach($tests as $n => $test) {
4242
?>
4343
===DONE===
4444
<?php exit(0); ?>
45-
--EXPECT--
45+
--EXPECTF--
4646
Test#0 { "stuff" : [ "class", "data" ] }
4747
0 : 2f 00 00 00 04 73 74 75 66 66 00 23 00 00 00 02 [/....stuff.#....]
4848
10 : 72 61 6e 64 6f 6d 00 06 00 00 00 63 6c 61 73 73 [random.....class]
@@ -54,6 +54,12 @@ array(2) {
5454
[0]=>
5555
string(4) "data"
5656
}
57+
string(24) "MyClass::bsonUnserialize"
58+
array(1) {
59+
["stuff"]=>
60+
object(MyClass)#%d (0) {
61+
}
62+
}
5763
Test#1 { "stuff" : [ 1, 2, 3 ] }
5864
0 : 26 00 00 00 04 73 74 75 66 66 00 1a 00 00 00 10 [&....stuff......]
5965
10 : 30 00 01 00 00 00 10 31 00 02 00 00 00 10 32 00 [0......1......2.]
@@ -67,4 +73,10 @@ array(3) {
6773
[2]=>
6874
int(3)
6975
}
76+
string(25) "MyClass2::bsonUnserialize"
77+
array(1) {
78+
["stuff"]=>
79+
object(MyClass2)#%d (0) {
80+
}
81+
}
7082
===DONE===

0 commit comments

Comments
 (0)