1 /* 2 * Copyright 2014-2017 MongoDB, 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 PHONGO_H 18 #define PHONGO_H 19 20 /* External libs */ 21 #include "bson/bson.h" 22 #include "mongoc/mongoc.h" 23 24 #include "phongo_version.h" 25 #include "phongo_compat.h" 26 #include "php_phongo_classes.h" 27 28 #define phpext_mongodb_ptr &mongodb_module_entry 29 extern zend_module_entry mongodb_module_entry; 30 31 /* Structure for persisted libmongoc clients. The PID is included to ensure that 32 * processes do not destroy clients created by other processes (relevant for 33 * forking). We avoid using pid_t for Windows compatibility. */ 34 typedef struct { 35 mongoc_client_t* client; 36 int created_by_pid; 37 int last_reset_by_pid; 38 } php_phongo_pclient_t; 39 40 ZEND_BEGIN_MODULE_GLOBALS(mongodb) 41 char* debug; 42 FILE* debug_fd; 43 bson_mem_vtable_t bsonMemVTable; 44 HashTable pclients; 45 HashTable* subscribers; 46 ZEND_END_MODULE_GLOBALS(mongodb) 47 48 #define MONGODB_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(mongodb, v) 49 #if defined(ZTS) && defined(COMPILE_DL_MONGODB) 50 ZEND_TSRMLS_CACHE_EXTERN() 51 #endif 52 53 #define PHONGO_WRITE_CONCERN_W_MAJORITY "majority" 54 55 /* This enum is necessary since mongoc_server_description_type_t is private and 56 * we need to translate strings returned by mongoc_server_description_type() to 57 * Server integer constants. */ 58 typedef enum { 59 PHONGO_SERVER_UNKNOWN = 0, 60 PHONGO_SERVER_STANDALONE = 1, 61 PHONGO_SERVER_MONGOS = 2, 62 PHONGO_SERVER_POSSIBLE_PRIMARY = 3, 63 PHONGO_SERVER_RS_PRIMARY = 4, 64 PHONGO_SERVER_RS_SECONDARY = 5, 65 PHONGO_SERVER_RS_ARBITER = 6, 66 PHONGO_SERVER_RS_OTHER = 7, 67 PHONGO_SERVER_RS_GHOST = 8, 68 PHONGO_SERVER_DESCRIPTION_TYPES = 9, 69 } php_phongo_server_description_type_t; 70 71 typedef struct { 72 php_phongo_server_description_type_t type; 73 const char* name; 74 } php_phongo_server_description_type_map_t; 75 76 extern php_phongo_server_description_type_map_t php_phongo_server_description_type_map[]; 77 78 typedef enum { 79 PHONGO_ERROR_INVALID_ARGUMENT = 1, 80 PHONGO_ERROR_RUNTIME = 2, 81 PHONGO_ERROR_UNEXPECTED_VALUE = 8, 82 PHONGO_ERROR_MONGOC_FAILED = 3, 83 PHONGO_ERROR_CONNECTION_FAILED = 7, 84 PHONGO_ERROR_LOGIC = 9 85 } php_phongo_error_domain_t; 86 87 /* This constant is used for determining if a server error for an exceeded query 88 * or command should select ExecutionTimeoutException. */ 89 #define PHONGO_SERVER_ERROR_EXCEEDED_TIME_LIMIT 50 90 91 zend_class_entry* phongo_exception_from_mongoc_domain(uint32_t /* mongoc_error_domain_t */ domain, uint32_t /* mongoc_error_code_t */ code); 92 zend_class_entry* phongo_exception_from_phongo_domain(php_phongo_error_domain_t domain); 93 void phongo_throw_exception(php_phongo_error_domain_t domain, const char* format, ...); 94 void phongo_throw_exception_from_bson_error_t(bson_error_t* error); 95 void phongo_throw_exception_from_bson_error_t_and_reply(bson_error_t* error, const bson_t* reply); 96 97 /* This enum is used for processing options in phongo_execute_parse_options and 98 * selecting a libmongoc function to use in phongo_execute_command. The values 99 * are important, as READ and WRITE are also used as a bit field to determine 100 * whether readPreference, readConcern, and writeConcern options are parsed. */ 101 typedef enum { 102 PHONGO_OPTION_READ_CONCERN = 0x01, 103 PHONGO_OPTION_READ_PREFERENCE = 0x02, 104 PHONGO_OPTION_WRITE_CONCERN = 0x04, 105 PHONGO_COMMAND_RAW = 0x07, 106 PHONGO_COMMAND_READ = 0x03, 107 PHONGO_COMMAND_WRITE = 0x04, 108 PHONGO_COMMAND_READ_WRITE = 0x05, 109 } php_phongo_command_type_t; 110 111 zend_object_handlers* phongo_get_std_object_handlers(void); 112 113 void phongo_clientencryption_init(php_phongo_clientencryption_t* ce_obj, mongoc_client_t* client, zval* options); 114 void phongo_server_init(zval* return_value, mongoc_client_t* client, uint32_t server_id); 115 void phongo_session_init(zval* return_value, mongoc_client_session_t* client_session); 116 void phongo_readconcern_init(zval* return_value, const mongoc_read_concern_t* read_concern); 117 void phongo_readpreference_init(zval* return_value, const mongoc_read_prefs_t* read_prefs); 118 void phongo_writeconcern_init(zval* return_value, const mongoc_write_concern_t* write_concern); 119 bool phongo_execute_bulk_write(mongoc_client_t* client, const char* namespace, php_phongo_bulkwrite_t* bulk_write, zval* zwriteConcern, uint32_t server_id, zval* return_value); 120 bool phongo_execute_command(mongoc_client_t* client, php_phongo_command_type_t type, const char* db, zval* zcommand, zval* zreadPreference, uint32_t server_id, zval* return_value); 121 bool phongo_execute_query(mongoc_client_t* client, const char* namespace, zval* zquery, zval* zreadPreference, uint32_t server_id, zval* return_value); 122 123 bool phongo_cursor_advance_and_check_for_error(mongoc_cursor_t* cursor); 124 125 const mongoc_read_concern_t* phongo_read_concern_from_zval(zval* zread_concern); 126 const mongoc_read_prefs_t* phongo_read_preference_from_zval(zval* zread_preference); 127 const mongoc_write_concern_t* phongo_write_concern_from_zval(zval* zwrite_concern); 128 129 php_phongo_server_description_type_t php_phongo_server_description_type(mongoc_server_description_t* sd); 130 131 bool phongo_parse_read_preference(zval* options, zval** zreadPreference); 132 bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession); 133 134 zval* php_phongo_prep_legacy_option(zval* options, const char* key, bool* allocated); 135 void php_phongo_prep_legacy_option_free(zval* options); 136 137 void php_phongo_read_preference_prep_tagsets(zval* tagSets); 138 bool php_phongo_read_preference_tags_are_valid(const bson_t* tags); 139 140 bool php_phongo_server_to_zval(zval* retval, mongoc_server_description_t* sd); 141 void php_phongo_read_concern_to_zval(zval* retval, const mongoc_read_concern_t* read_concern); 142 void php_phongo_write_concern_to_zval(zval* retval, const mongoc_write_concern_t* write_concern); 143 void php_phongo_cursor_to_zval(zval* retval, const mongoc_cursor_t* cursor); 144 145 void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, zval* options, zval* driverOptions); 146 int php_phongo_set_monitoring_callbacks(mongoc_client_t* client); 147 148 bool php_phongo_parse_int64(int64_t* retval, const char* data, size_t data_len); 149 150 void phongo_clientencryption_create_datakey(php_phongo_clientencryption_t* clientencryption, zval* return_value, char* kms_provider, zval* options); 151 void phongo_clientencryption_encrypt(php_phongo_clientencryption_t* clientencryption, zval* zvalue, zval* zciphertext, zval* options); 152 void phongo_clientencryption_decrypt(php_phongo_clientencryption_t* clientencryption, zval* zciphertext, zval* zvalue); 153 154 zend_bool phongo_writeerror_init(zval* return_value, bson_t* bson); 155 zend_bool phongo_writeconcernerror_init(zval* return_value, bson_t* bson); 156 157 void php_phongo_client_reset_once(mongoc_client_t* client, int pid); 158 159 #define PHONGO_CE_FINAL(ce) \ 160 do { \ 161 ce->ce_flags |= ZEND_ACC_FINAL; \ 162 } while (0); 163 164 #define PHONGO_CE_DISABLE_SERIALIZATION(ce) \ 165 do { \ 166 ce->serialize = zend_class_serialize_deny; \ 167 ce->unserialize = zend_class_unserialize_deny; \ 168 } while (0); 169 170 #define PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, size) \ 171 do { \ 172 if (is_debug) { \ 173 ALLOC_HASHTABLE(props); \ 174 zend_hash_init((props), (size), NULL, ZVAL_PTR_DTOR, 0); \ 175 } else if ((intern)->properties) { \ 176 (props) = (intern)->properties; \ 177 } else { \ 178 ALLOC_HASHTABLE(props); \ 179 zend_hash_init((props), (size), NULL, ZVAL_PTR_DTOR, 0); \ 180 (intern)->properties = (props); \ 181 } \ 182 } while (0); 183 184 #define PHONGO_GET_PROPERTY_HASH_FREE_PROPS(is_debug, props) \ 185 do { \ 186 if (is_debug) { \ 187 zend_hash_destroy((props)); \ 188 FREE_HASHTABLE(props); \ 189 } \ 190 } while (0); 191 192 #define PHONGO_ZVAL_CLASS_OR_TYPE_NAME(zv) (Z_TYPE(zv) == IS_OBJECT ? ZSTR_VAL(Z_OBJCE(zv)->name) : zend_get_type_by_const(Z_TYPE(zv))) 193 #define PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(zvp) PHONGO_ZVAL_CLASS_OR_TYPE_NAME(*(zvp)) 194 195 #define PHONGO_ZVAL_EXCEPTION_NAME(e) (ZSTR_VAL(e->ce->name)) 196 197 #define PHONGO_SET_CREATED_BY_PID(intern) \ 198 do { \ 199 (intern)->created_by_pid = (int) getpid(); \ 200 } while (0); 201 202 #define PHONGO_RESET_CLIENT_IF_PID_DIFFERS(intern) \ 203 do { \ 204 int pid = (int) getpid(); \ 205 if ((intern)->created_by_pid != pid) { \ 206 php_phongo_client_reset_once((intern)->client, pid); \ 207 } \ 208 } while (0); 209 210 #endif /* PHONGO_H */ 211 212 /* 213 * Local variables: 214 * tab-width: 4 215 * c-basic-offset: 4 216 * End: 217 * vim600: noet sw=4 ts=4 fdm=marker 218 * vim<600: noet sw=4 ts=4 219 */ 220