Skip to content

Commit 5ce5697

Browse files
committed
PHPC-619: Implement Decimal BSON type
1 parent 5af7496 commit 5ce5697

13 files changed

+433
-3
lines changed

config.m4

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ if test "$MONGODB" != "no"; then
142142
src/BSON/Serializable.c \
143143
src/BSON/Persistable.c \
144144
src/BSON/Binary.c \
145+
src/BSON/Decimal128.c \
145146
src/BSON/Javascript.c \
146147
src/BSON/MaxKey.c \
147148
src/BSON/MinKey.c \
@@ -205,6 +206,7 @@ if test "$MONGODB" != "no"; then
205206
bson-atomic.c \
206207
bson-clock.c \
207208
bson-context.c \
209+
bson-decimal128.c \
208210
bson-error.c \
209211
bson-iter.c \
210212
bson-iso8601.c \

config.w32

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ if (PHP_MONGODB != "no") {
1010
EXTENSION("mongodb", "php_phongo.c");
1111
ADD_SOURCES(configure_module_dirname + "/", "phongo_compat.c", "mongodb");
1212
ADD_SOURCES(configure_module_dirname + "/src", "bson.c", "mongodb");
13-
ADD_SOURCES(configure_module_dirname + "/src/BSON", "Type.c Unserializable.c Serializable.c Persistable.c Binary.c Javascript.c MaxKey.c MinKey.c ObjectID.c Regex.c Timestamp.c UTCDateTime.c", "mongodb");
13+
ADD_SOURCES(configure_module_dirname + "/src/BSON", "Type.c Unserializable.c Serializable.c Persistable.c Binary.c Decimal128.c Javascript.c MaxKey.c MinKey.c ObjectID.c Regex.c Timestamp.c UTCDateTime.c", "mongodb");
1414
ADD_SOURCES(configure_module_dirname + "/src/MongoDB", "Command.c Cursor.c CursorId.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c BulkWrite.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c", "mongodb");
1515
ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Exception", "Exception.c LogicException.c RuntimeException.c UnexpectedValueException.c InvalidArgumentException.c ConnectionException.c AuthenticationException.c SSLConnectionException.c ExecutionTimeoutException.c ConnectionTimeoutException.c WriteException.c BulkWriteException.c", "mongodb");
1616
ADD_SOURCES(configure_module_dirname + "/src/contrib/", "php-ssl.c", "mongodb");
1717
ADD_SOURCES(configure_module_dirname + "/src/libbson/src/yajl", "yajl_version.c yajl.c yajl_encode.c yajl_lex.c yajl_parser.c yajl_buf.c yajl_tree.c yajl_alloc.c yajl_gen.c", "mongodb");
18-
ADD_SOURCES(configure_module_dirname + "/src/libbson/src/bson", "bcon.c bson.c bson-atomic.c bson-clock.c bson-context.c bson-error.c bson-iter.c bson-iso8601.c bson-json.c bson-keys.c bson-md5.c bson-memory.c bson-oid.c bson-reader.c bson-string.c bson-timegm.c bson-utf8.c bson-value.c bson-version-functions.c bson-writer.c", "mongodb");
18+
ADD_SOURCES(configure_module_dirname + "/src/libbson/src/bson", "bcon.c bson.c bson-atomic.c bson-clock.c bson-context.c bson-decimal128.c bson-error.c bson-iter.c bson-iso8601.c bson-json.c bson-keys.c bson-md5.c bson-memory.c bson-oid.c bson-reader.c bson-string.c bson-timegm.c bson-utf8.c bson-value.c bson-version-functions.c bson-writer.c", "mongodb");
1919
ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-b64.c mongoc-client.c mongoc-client-pool.c mongoc-cluster.c mongoc-collection.c mongoc-counters.c mongoc-cursor.c mongoc-cursor-array.c mongoc-cursor-cursorid.c mongoc-cursor-transform.c mongoc-database.c mongoc-find-and-modify.c mongoc-host-list.c mongoc-init.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-page.c mongoc-gridfs-file-list.c mongoc-index.c mongoc-list.c mongoc-log.c mongoc-matcher-op.c mongoc-matcher.c mongoc-memcmp.c mongoc-opcode.c mongoc-queue.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-server-description.c mongoc-server-stream.c mongoc-set.c mongoc-socket.c mongoc-stream.c mongoc-stream-buffered.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-socket.c mongoc-topology.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-concern.c", "mongodb");
2020
ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-crypto.c mongoc-scram.c", "mongodb");
2121
ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-stream-tls.c mongoc-ssl.c", "mongodb");

php_phongo.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,17 @@ void php_phongo_new_binary_from_binary_and_type(zval *object, const char *data,
20962096
intern->data_len = data_len;
20972097
intern->type = (uint8_t) type;
20982098
} /* }}} */
2099+
2100+
void php_phongo_new_decimal128(zval *object, const bson_decimal128_t *decimal TSRMLS_DC) /* {{{ */
2101+
{
2102+
php_phongo_decimal128_t *intern;
2103+
2104+
object_init_ex(object, php_phongo_decimal128_ce);
2105+
2106+
intern = Z_DECIMAL128_OBJ_P(object);
2107+
memcpy(&intern->decimal, decimal, sizeof(bson_decimal128_t));
2108+
} /* }}} */
2109+
20992110
void php_phongo_new_regex_from_regex_and_options(zval *object, const char *pattern, const char *flags TSRMLS_DC) /* {{{ */
21002111
{
21012112
php_phongo_regex_t *intern;
@@ -2492,6 +2503,7 @@ PHP_MINIT_FUNCTION(mongodb)
24922503
PHP_MINIT(Unserializable)(INIT_FUNC_ARGS_PASSTHRU);
24932504
PHP_MINIT(Persistable)(INIT_FUNC_ARGS_PASSTHRU);
24942505
PHP_MINIT(Binary)(INIT_FUNC_ARGS_PASSTHRU);
2506+
PHP_MINIT(Decimal128)(INIT_FUNC_ARGS_PASSTHRU);
24952507
PHP_MINIT(Javascript)(INIT_FUNC_ARGS_PASSTHRU);
24962508
PHP_MINIT(MaxKey)(INIT_FUNC_ARGS_PASSTHRU);
24972509
PHP_MINIT(MinKey)(INIT_FUNC_ARGS_PASSTHRU);

php_phongo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ void php_phongo_new_timestamp_from_increment_and_timestamp(zval *object, uint32_
168168
void php_phongo_new_javascript_from_javascript(int init, zval *object, const char *code, size_t code_len TSRMLS_DC);
169169
void php_phongo_new_javascript_from_javascript_and_scope(int init, zval *object, const char *code, size_t code_len, const bson_t *scope TSRMLS_DC);
170170
void php_phongo_new_binary_from_binary_and_type(zval *object, const char *data, size_t data_len, bson_subtype_t type TSRMLS_DC);
171+
void php_phongo_new_decimal128(zval *object, const bson_decimal128_t *decimal TSRMLS_DC);
171172
void php_phongo_new_regex_from_regex_and_options(zval *object, const char *pattern, const char *flags TSRMLS_DC);
172173

173174
zend_bool phongo_writeerror_init(zval *return_value, bson_t *bson TSRMLS_DC);

php_phongo_classes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
# define Z_WRITEERROR_OBJ_P(zv) (php_writeerror_fetch_object(Z_OBJ_P(zv)))
3737
# define Z_WRITERESULT_OBJ_P(zv) (php_writeresult_fetch_object(Z_OBJ_P(zv)))
3838
# define Z_BINARY_OBJ_P(zv) (php_binary_fetch_object(Z_OBJ_P(zv)))
39+
# define Z_DECIMAL128_OBJ_P(zv) (php_decimal128_fetch_object(Z_OBJ_P(zv)))
3940
# define Z_INT32_OBJ_P(zv) (php_int32_fetch_object(Z_OBJ_P(zv)))
4041
# define Z_INT64_OBJ_P(zv) (php_int64_fetch_object(Z_OBJ_P(zv)))
4142
# define Z_JAVASCRIPT_OBJ_P(zv) (php_javascript_fetch_object(Z_OBJ_P(zv)))
@@ -61,6 +62,7 @@
6162
# define Z_OBJ_WRITEERROR(zo) (php_writeerror_fetch_object(zo))
6263
# define Z_OBJ_WRITERESULT(zo) (php_writeresult_fetch_object(zo))
6364
# define Z_OBJ_BINARY(zo) (php_binary_fetch_object(zo))
65+
# define Z_OBJ_DECIMAL128(zo) (php_decimal128_fetch_object(zo))
6466
# define Z_OBJ_INT32(zo) (php_int32_fetch_object(zo))
6567
# define Z_OBJ_INT64(zo) (php_int64_fetch_object(zo))
6668
# define Z_OBJ_JAVASCRIPT(zo) (php_javascript_fetch_object(zo))
@@ -90,6 +92,7 @@
9092
# define Z_WRITEERROR_OBJ_P(zv) ((php_phongo_writeerror_t *)zend_object_store_get_object(zv TSRMLS_CC))
9193
# define Z_WRITERESULT_OBJ_P(zv) ((php_phongo_writeresult_t *)zend_object_store_get_object(zv TSRMLS_CC))
9294
# define Z_BINARY_OBJ_P(zv) ((php_phongo_binary_t *)zend_object_store_get_object(zv TSRMLS_CC))
95+
# define Z_DECIMAL128_OBJ_P(zv) ((php_phongo_decimal128_t *)zend_object_store_get_object(zv TSRMLS_CC))
9396
# define Z_INT32_OBJ_P(zv) ((php_phongo_int32_t *)zend_object_store_get_object(zv TSRMLS_CC))
9497
# define Z_INT64_OBJ_P(zv) ((php_phongo_int64_t *)zend_object_store_get_object(zv TSRMLS_CC))
9598
# define Z_JAVASCRIPT_OBJ_P(zv) ((php_phongo_javascript_t *)zend_object_store_get_object(zv TSRMLS_CC))
@@ -115,6 +118,7 @@
115118
# define Z_OBJ_WRITEERROR(zo) ((php_phongo_writeerror_t *)zo)
116119
# define Z_OBJ_WRITERESULT(zo) ((php_phongo_writeresult_t *)zo)
117120
# define Z_OBJ_BINARY(zo) ((php_phongo_binary_t *)zo)
121+
# define Z_OBJ_DECIMAL128(zo) ((php_phongo_decimal128_t *)zo)
118122
# define Z_OBJ_INT32(zo) ((php_phongo_int32_t *)zo)
119123
# define Z_OBJ_INT64(zo) ((php_phongo_int64_t *)zo)
120124
# define Z_OBJ_JAVASCRIPT(zo) ((php_phongo_javascript_t *)zo)
@@ -166,6 +170,7 @@ extern PHONGO_API zend_class_entry *php_phongo_persistable_ce;
166170
extern PHONGO_API zend_class_entry *php_phongo_unserializable_ce;
167171
extern PHONGO_API zend_class_entry *php_phongo_serializable_ce;
168172
extern PHONGO_API zend_class_entry *php_phongo_binary_ce;
173+
extern PHONGO_API zend_class_entry *php_phongo_decimal128_ce;
169174
extern PHONGO_API zend_class_entry *php_phongo_int32_ce;
170175
extern PHONGO_API zend_class_entry *php_phongo_int64_ce;
171176
extern PHONGO_API zend_class_entry *php_phongo_javascript_ce;
@@ -215,6 +220,7 @@ PHP_MINIT_FUNCTION(Unserializable);
215220
PHP_MINIT_FUNCTION(Serializable);
216221
PHP_MINIT_FUNCTION(Persistable);
217222
PHP_MINIT_FUNCTION(Binary);
223+
PHP_MINIT_FUNCTION(Decimal128);
218224
PHP_MINIT_FUNCTION(Javascript);
219225
PHP_MINIT_FUNCTION(MaxKey);
220226
PHP_MINIT_FUNCTION(MinKey);

php_phongo_structs-5.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ typedef struct {
138138
int data_len;
139139
uint8_t type;
140140
} php_phongo_binary_t;
141+
142+
typedef struct {
143+
zend_object std;
144+
bson_decimal128_t decimal;
145+
} php_phongo_decimal128_t;
146+
141147
typedef struct {
142148
zend_object std;
143149
} php_phongo_int32_t;

php_phongo_structs-7.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ typedef struct {
138138
int type;
139139
zend_object std;
140140
} php_phongo_binary_t;
141+
142+
typedef struct {
143+
bson_decimal128_t decimal;
144+
zend_object std;
145+
} php_phongo_decimal128_t;
146+
141147
typedef struct {
142148
zend_object std;
143149
} php_phongo_int32_t;
@@ -222,6 +228,9 @@ static inline php_phongo_writeresult_t* php_writeresult_fetch_object(zend_object
222228
static inline php_phongo_binary_t* php_binary_fetch_object(zend_object *obj) {
223229
return (php_phongo_binary_t *)((char *)obj - XtOffsetOf(php_phongo_binary_t, std));
224230
}
231+
static inline php_phongo_decimal128_t* php_decimal128_fetch_object(zend_object *obj) {
232+
return (php_phongo_decimal128_t *)((char *)obj - XtOffsetOf(php_phongo_decimal128_t, std));
233+
}
225234
static inline php_phongo_int32_t* php_int32_fetch_object(zend_object *obj) {
226235
return (php_phongo_int32_t *)((char *)obj - XtOffsetOf(php_phongo_int32_t, std));
227236
}

src/BSON/Decimal128.c

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*
2+
+---------------------------------------------------------------------------+
3+
| PHP Driver for MongoDB |
4+
+---------------------------------------------------------------------------+
5+
| Copyright 2013-2016 MongoDB, Inc. |
6+
| |
7+
| Licensed under the Apache License, Version 2.0 (the "License"); |
8+
| you may not use this file except in compliance with the License. |
9+
| You may obtain a copy of the License at |
10+
| |
11+
| http://www.apache.org/licenses/LICENSE-2.0 |
12+
| |
13+
| Unless required by applicable law or agreed to in writing, software |
14+
| distributed under the License is distributed on an "AS IS" BASIS, |
15+
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16+
| See the License for the specific language governing permissions and |
17+
| limitations under the License. |
18+
+---------------------------------------------------------------------------+
19+
| Copyright (c) 2014-2016 MongoDB, Inc. |
20+
+---------------------------------------------------------------------------+
21+
*/
22+
23+
#ifdef HAVE_CONFIG_H
24+
# include "config.h"
25+
#endif
26+
27+
/* External libs */
28+
#include <bson.h>
29+
#include <mongoc.h>
30+
31+
/* PHP Core stuff */
32+
#include <php.h>
33+
#include <php_ini.h>
34+
#include <ext/standard/info.h>
35+
#include <Zend/zend_interfaces.h>
36+
#include <ext/spl/spl_iterators.h>
37+
/* Our Compatability header */
38+
#include "phongo_compat.h"
39+
40+
/* Our stuffz */
41+
#include "php_phongo.h"
42+
#include "php_bson.h"
43+
44+
45+
PHONGO_API zend_class_entry *php_phongo_decimal128_ce;
46+
47+
zend_object_handlers php_phongo_handler_decimal128;
48+
49+
/* {{{ proto BSON\Decimal128 Decimal128::__construct(string $value)
50+
Construct a new BSON Decimal128 type */
51+
PHP_METHOD(Decimal128, __construct)
52+
{
53+
php_phongo_decimal128_t *intern;
54+
zend_error_handling error_handling;
55+
char *value;
56+
phongo_zpp_char_len value_len;
57+
58+
59+
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
60+
intern = Z_DECIMAL128_OBJ_P(getThis());
61+
62+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
63+
zend_restore_error_handling(&error_handling TSRMLS_CC);
64+
return;
65+
}
66+
zend_restore_error_handling(&error_handling TSRMLS_CC);
67+
68+
if ( ! bson_decimal128_from_string(value, &intern->decimal)) {
69+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing decimal string: %s", value);
70+
return;
71+
}
72+
}
73+
/* }}} */
74+
75+
/* {{{ proto void Decimal128::__toString()
76+
*/
77+
PHP_METHOD(Decimal128, __toString)
78+
{
79+
php_phongo_decimal128_t *intern;
80+
char outbuf[BSON_DECIMAL128_STRING];
81+
82+
intern = Z_DECIMAL128_OBJ_P(getThis());
83+
84+
if (zend_parse_parameters_none() == FAILURE) {
85+
return;
86+
}
87+
88+
bson_decimal128_to_string(&intern->decimal, outbuf);
89+
90+
PHONGO_RETURN_STRING(outbuf);
91+
}
92+
/* }}} */
93+
94+
95+
/* {{{ BSON\Decimal128 */
96+
97+
ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128___construct, 0, 0, 2)
98+
ZEND_ARG_INFO(0, value)
99+
ZEND_END_ARG_INFO();
100+
101+
ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128___toString, 0, 0, 0)
102+
ZEND_END_ARG_INFO();
103+
104+
105+
static zend_function_entry php_phongo_decimal128_me[] = {
106+
PHP_ME(Decimal128, __construct, ai_Decimal128___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
107+
PHP_ME(Decimal128, __toString, ai_Decimal128___toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
108+
PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC)
109+
PHP_FE_END
110+
};
111+
112+
/* }}} */
113+
114+
115+
/* {{{ php_phongo_decimal128_t object handlers */
116+
static void php_phongo_decimal128_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */
117+
{
118+
php_phongo_decimal128_t *intern = Z_OBJ_DECIMAL128(object);
119+
120+
zend_object_std_dtor(&intern->std TSRMLS_CC);
121+
122+
#if PHP_VERSION_ID < 70000
123+
efree(intern);
124+
#endif
125+
} /* }}} */
126+
127+
phongo_create_object_retval php_phongo_decimal128_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
128+
{
129+
php_phongo_decimal128_t *intern = NULL;
130+
131+
intern = PHONGO_ALLOC_OBJECT_T(php_phongo_decimal128_t, class_type);
132+
133+
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
134+
object_properties_init(&intern->std, class_type);
135+
136+
#if PHP_VERSION_ID >= 70000
137+
intern->std.handlers = &php_phongo_handler_decimal128;
138+
139+
return &intern->std;
140+
#else
141+
{
142+
zend_object_value retval;
143+
retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_decimal128_free_object, NULL TSRMLS_CC);
144+
retval.handlers = &php_phongo_handler_decimal128;
145+
146+
return retval;
147+
}
148+
#endif
149+
} /* }}} */
150+
151+
HashTable *php_phongo_decimal128_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
152+
{
153+
php_phongo_decimal128_t *intern;
154+
char outbuf[BSON_DECIMAL128_STRING] = "";
155+
#if PHP_VERSION_ID >= 70000
156+
zval retval;
157+
#else
158+
zval retval = zval_used_for_init;
159+
#endif
160+
161+
intern = Z_DECIMAL128_OBJ_P(object);
162+
*is_temp = 1;
163+
array_init_size(&retval, 1);
164+
165+
bson_decimal128_to_string(&intern->decimal, outbuf);
166+
ADD_ASSOC_STRING(&retval, "dec", outbuf);
167+
168+
return Z_ARRVAL(retval);
169+
} /* }}} */
170+
/* }}} */
171+
172+
/* {{{ PHP_MINIT_FUNCTION */
173+
PHP_MINIT_FUNCTION(Decimal128)
174+
{
175+
zend_class_entry ce;
176+
(void)type;(void)module_number;
177+
178+
INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Decimal128", php_phongo_decimal128_me);
179+
php_phongo_decimal128_ce = zend_register_internal_class(&ce TSRMLS_CC);
180+
php_phongo_decimal128_ce->create_object = php_phongo_decimal128_create_object;
181+
PHONGO_CE_INIT(php_phongo_decimal128_ce);
182+
183+
zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_phongo_type_ce);
184+
185+
memcpy(&php_phongo_handler_decimal128, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
186+
php_phongo_handler_decimal128.get_debug_info = php_phongo_decimal128_get_debug_info;
187+
#if PHP_VERSION_ID >= 70000
188+
php_phongo_handler_decimal128.free_obj = php_phongo_decimal128_free_object;
189+
php_phongo_handler_decimal128.offset = XtOffsetOf(php_phongo_decimal128_t, std);
190+
#endif
191+
192+
return SUCCESS;
193+
}
194+
/* }}} */
195+
196+
197+
198+
/*
199+
* Local variables:
200+
* tab-width: 4
201+
* c-basic-offset: 4
202+
* End:
203+
* vim600: noet sw=4 ts=4 fdm=marker
204+
* vim<600: noet sw=4 ts=4
205+
*/

0 commit comments

Comments
 (0)