1 /**
2  * Copyright 2015-2017 DataStax, 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 #include "php_driver.h"
18 #include "php_driver_globals.h"
19 #include "php_driver_types.h"
20 #include "version.h"
21 
22 #include "util/types.h"
23 #include "util/ref.h"
24 
25 #include <php_ini.h>
26 #include <ext/standard/info.h>
27 
28 #ifndef _WIN32
29 #include <php_syslog.h>
30 #else
31 #pragma message("syslog will be disabled on Windows")
32 #endif
33 
34 #include <ext/standard/info.h>
35 #include <fcntl.h>
36 #include <time.h>
37 #include <uv.h>
38 
39 /* Resources */
40 #define PHP_DRIVER_CLUSTER_RES_NAME PHP_DRIVER_NAMESPACE " Cluster"
41 #define PHP_DRIVER_SESSION_RES_NAME PHP_DRIVER_NAMESPACE " Session"
42 
43 static uv_once_t log_once = UV_ONCE_INIT;
44 static char *log_location = NULL;
45 static uv_rwlock_t log_lock;
46 
47 #if CURRENT_CPP_DRIVER_VERSION < CPP_DRIVER_VERSION(2, 6, 0)
48 #error C/C++ driver version 2.6.0 or greater required
49 #endif
50 
51 ZEND_DECLARE_MODULE_GLOBALS(php_driver)
52 
53 static PHP_GINIT_FUNCTION(php_driver);
54 static PHP_GSHUTDOWN_FUNCTION(php_driver);
55 
56 const zend_function_entry php_driver_functions[] = {
57   PHP_FE_END /* Must be the last line in php_driver_functions[] */
58 };
59 
60 #if ZEND_MODULE_API_NO >= 20050617
61 static zend_module_dep php_driver_deps[] = {
62   ZEND_MOD_REQUIRED("spl")
63   ZEND_MOD_END
64 };
65 #endif
66 
67 zend_module_entry php_driver_module_entry = {
68 #if ZEND_MODULE_API_NO >= 20050617
69   STANDARD_MODULE_HEADER_EX, NULL, php_driver_deps,
70 #elif ZEND_MODULE_API_NO >= 20010901
71   STANDARD_MODULE_HEADER,
72 #endif
73   PHP_DRIVER_NAME,
74   php_driver_functions,      /* Functions */
75   PHP_MINIT(php_driver),     /* MINIT */
76   PHP_MSHUTDOWN(php_driver), /* MSHUTDOWN */
77   PHP_RINIT(php_driver),     /* RINIT */
78   PHP_RSHUTDOWN(php_driver), /* RSHUTDOWN */
79   PHP_MINFO(php_driver),     /* MINFO */
80 #if ZEND_MODULE_API_NO >= 20010901
81   PHP_DRIVER_VERSION,
82 #endif
83   PHP_MODULE_GLOBALS(php_driver),
84   PHP_GINIT(php_driver),
85   PHP_GSHUTDOWN(php_driver),
86   NULL,
87   STANDARD_MODULE_PROPERTIES_EX
88 };
89 
90 #ifdef COMPILE_DL_CASSANDRA
91 ZEND_GET_MODULE(php_driver)
92 #endif
93 
94 PHP_INI_BEGIN()
95   PHP_DRIVER_INI_ENTRY_LOG
96   PHP_DRIVER_INI_ENTRY_LOG_LEVEL
97 PHP_INI_END()
98 
99 static int le_php_driver_cluster_res;
100 int
php_le_php_driver_cluster()101 php_le_php_driver_cluster()
102 {
103   return le_php_driver_cluster_res;
104 }
105 static void
php_driver_cluster_dtor(php5to7_zend_resource rsrc TSRMLS_DC)106 php_driver_cluster_dtor(php5to7_zend_resource rsrc TSRMLS_DC)
107 {
108   CassCluster *cluster = (CassCluster*) rsrc->ptr;
109 
110   if (cluster) {
111     cass_cluster_free(cluster);
112     PHP_DRIVER_G(persistent_clusters)--;
113     rsrc->ptr = NULL;
114   }
115 }
116 
117 static int le_php_driver_session_res;
118 int
php_le_php_driver_session()119 php_le_php_driver_session()
120 {
121   return le_php_driver_session_res;
122 }
123 static void
php_driver_session_dtor(php5to7_zend_resource rsrc TSRMLS_DC)124 php_driver_session_dtor(php5to7_zend_resource rsrc TSRMLS_DC)
125 {
126   php_driver_psession *psession = (php_driver_psession*) rsrc->ptr;
127 
128   if (psession) {
129     cass_future_free(psession->future);
130     php_driver_del_peref(&psession->session, 1);
131     pefree(psession, 1);
132     PHP_DRIVER_G(persistent_sessions)--;
133     rsrc->ptr = NULL;
134   }
135 }
136 
137 static void
138 php_driver_log(const CassLogMessage *message, void *data);
139 
140 static void
php_driver_log_cleanup()141 php_driver_log_cleanup()
142 {
143   cass_log_cleanup();
144   uv_rwlock_destroy(&log_lock);
145   if (log_location) {
146     free(log_location);
147     log_location = NULL;
148   }
149 }
150 
151 static void
php_driver_log_initialize()152 php_driver_log_initialize()
153 {
154   uv_rwlock_init(&log_lock);
155   cass_log_set_level(CASS_LOG_ERROR);
156   cass_log_set_callback(php_driver_log, NULL);
157 }
158 
159 static void
php_driver_log(const CassLogMessage * message,void * data)160 php_driver_log(const CassLogMessage *message, void *data)
161 {
162   char log[MAXPATHLEN + 1];
163   uint log_length = 0;
164 
165   /* Making a copy here because location could be updated by a PHP thread. */
166   uv_rwlock_rdlock(&log_lock);
167   if (log_location) {
168     log_length = MIN(strlen(log_location), MAXPATHLEN);
169     memcpy(log, log_location, log_length);
170   }
171   uv_rwlock_rdunlock(&log_lock);
172 
173   log[log_length] = '\0';
174 
175   if (log_length > 0) {
176     FILE *fd = NULL;
177 #ifndef _WIN32
178     if (!strcmp(log, "syslog")) {
179       php_syslog(LOG_NOTICE, PHP_DRIVER_NAME " | [%s] %s (%s:%d)",
180                  cass_log_level_string(message->severity), message->message,
181                  message->file, message->line);
182       return;
183     }
184 #endif
185 
186     fd = fopen(log, "a");
187     if (fd) {
188       time_t log_time;
189       struct tm log_tm;
190       char log_time_str[64];
191       size_t needed = 0;
192       char *tmp     = NULL;
193 
194       time(&log_time);
195       php_localtime_r(&log_time, &log_tm);
196       strftime(log_time_str, sizeof(log_time_str), "%d-%m-%Y %H:%M:%S %Z", &log_tm);
197 
198       needed = snprintf(NULL, 0, "%s [%s] %s (%s:%d)%s",
199                         log_time_str,
200                         cass_log_level_string(message->severity), message->message,
201                         message->file, message->line,
202                         PHP_EOL);
203 
204       tmp = malloc(needed + 1);
205       sprintf(tmp, "%s [%s] %s (%s:%d)%s",
206               log_time_str,
207               cass_log_level_string(message->severity), message->message,
208               message->file, message->line,
209               PHP_EOL);
210 
211       fwrite(tmp, 1, needed, fd);
212       free(tmp);
213       fclose(fd);
214       return;
215     }
216   }
217 
218   /* This defaults to using "stderr" instead of "sapi_module.log_message"
219    * because there are no guarantees that all implementations of the SAPI
220    * logging function are thread-safe.
221    */
222 
223   fprintf(stderr, PHP_DRIVER_NAME " | [%s] %s (%s:%d)%s",
224           cass_log_level_string(message->severity), message->message,
225           message->file, message->line,
226           PHP_EOL);
227 }
228 
229 zend_class_entry*
exception_class(CassError rc)230 exception_class(CassError rc)
231 {
232   switch (rc) {
233   case CASS_ERROR_LIB_BAD_PARAMS:
234   case CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS:
235   case CASS_ERROR_LIB_INVALID_ITEM_COUNT:
236   case CASS_ERROR_LIB_INVALID_VALUE_TYPE:
237   case CASS_ERROR_LIB_INVALID_STATEMENT_TYPE:
238   case CASS_ERROR_LIB_NAME_DOES_NOT_EXIST:
239   case CASS_ERROR_LIB_NULL_VALUE:
240   case CASS_ERROR_SSL_INVALID_CERT:
241   case CASS_ERROR_SSL_INVALID_PRIVATE_KEY:
242   case CASS_ERROR_SSL_NO_PEER_CERT:
243   case CASS_ERROR_SSL_INVALID_PEER_CERT:
244   case CASS_ERROR_SSL_IDENTITY_MISMATCH:
245     return php_driver_invalid_argument_exception_ce;
246   case CASS_ERROR_LIB_NO_STREAMS:
247   case CASS_ERROR_LIB_UNABLE_TO_INIT:
248   case CASS_ERROR_LIB_MESSAGE_ENCODE:
249   case CASS_ERROR_LIB_HOST_RESOLUTION:
250   case CASS_ERROR_LIB_UNEXPECTED_RESPONSE:
251   case CASS_ERROR_LIB_REQUEST_QUEUE_FULL:
252   case CASS_ERROR_LIB_NO_AVAILABLE_IO_THREAD:
253   case CASS_ERROR_LIB_WRITE_ERROR:
254   case CASS_ERROR_LIB_NO_HOSTS_AVAILABLE:
255   case CASS_ERROR_LIB_UNABLE_TO_SET_KEYSPACE:
256   case CASS_ERROR_LIB_UNABLE_TO_DETERMINE_PROTOCOL:
257   case CASS_ERROR_LIB_UNABLE_TO_CONNECT:
258   case CASS_ERROR_LIB_UNABLE_TO_CLOSE:
259     return php_driver_runtime_exception_ce;
260   case CASS_ERROR_LIB_REQUEST_TIMED_OUT:
261     return php_driver_timeout_exception_ce;
262   case CASS_ERROR_LIB_CALLBACK_ALREADY_SET:
263   case CASS_ERROR_LIB_NOT_IMPLEMENTED:
264     return php_driver_logic_exception_ce;
265   case CASS_ERROR_SERVER_SERVER_ERROR:
266     return php_driver_server_exception_ce;
267   case CASS_ERROR_SERVER_PROTOCOL_ERROR:
268     return php_driver_protocol_exception_ce;
269   case CASS_ERROR_SERVER_BAD_CREDENTIALS:
270     return php_driver_authentication_exception_ce;
271   case CASS_ERROR_SERVER_UNAVAILABLE:
272     return php_driver_unavailable_exception_ce;
273   case CASS_ERROR_SERVER_OVERLOADED:
274     return php_driver_overloaded_exception_ce;
275   case CASS_ERROR_SERVER_IS_BOOTSTRAPPING:
276     return php_driver_is_bootstrapping_exception_ce;
277   case CASS_ERROR_SERVER_TRUNCATE_ERROR:
278     return php_driver_truncate_exception_ce;
279   case CASS_ERROR_SERVER_WRITE_TIMEOUT:
280     return php_driver_write_timeout_exception_ce;
281   case CASS_ERROR_SERVER_READ_TIMEOUT:
282     return php_driver_read_timeout_exception_ce;
283   case CASS_ERROR_SERVER_SYNTAX_ERROR:
284     return php_driver_invalid_syntax_exception_ce;
285   case CASS_ERROR_SERVER_UNAUTHORIZED:
286     return php_driver_unauthorized_exception_ce;
287   case CASS_ERROR_SERVER_INVALID_QUERY:
288     return php_driver_invalid_query_exception_ce;
289   case CASS_ERROR_SERVER_CONFIG_ERROR:
290     return php_driver_configuration_exception_ce;
291   case CASS_ERROR_SERVER_ALREADY_EXISTS:
292     return php_driver_already_exists_exception_ce;
293   case CASS_ERROR_SERVER_UNPREPARED:
294     return php_driver_unprepared_exception_ce;
295   default:
296     return php_driver_runtime_exception_ce;
297   }
298 }
299 
300 void
throw_invalid_argument(zval * object,const char * object_name,const char * expected_type TSRMLS_DC)301 throw_invalid_argument(zval *object,
302                        const char *object_name,
303                        const char *expected_type TSRMLS_DC)
304 {
305   if (Z_TYPE_P(object) == IS_OBJECT) {
306 #if ZEND_MODULE_API_NO >= 20100525
307     const char* cls_name = NULL;
308 #else
309     char* cls_name = NULL;
310 #endif
311 
312 #if PHP_MAJOR_VERSION >= 7
313     size_t cls_len;
314 #else
315     zend_uint cls_len;
316 #endif
317 
318 #if PHP_MAJOR_VERSION >= 7
319     zend_string* str  = Z_OBJ_HANDLER_P(object, get_class_name)(Z_OBJ_P(object) TSRMLS_CC);
320     cls_name = str->val;
321     cls_len = str->len;
322 #else
323     Z_OBJ_HANDLER_P(object, get_class_name)(object, &cls_name, &cls_len, 0 TSRMLS_CC);
324 #endif
325     if (cls_name) {
326       zend_throw_exception_ex(php_driver_invalid_argument_exception_ce, 0 TSRMLS_CC,
327                               "%s must be %s, an instance of %.*s given",
328                               object_name, expected_type, (int)cls_len, cls_name);
329 #if PHP_MAJOR_VERSION >= 7
330       zend_string_release(str);
331 #else
332       efree((void*) cls_name);
333 #endif
334     } else {
335       zend_throw_exception_ex(php_driver_invalid_argument_exception_ce, 0 TSRMLS_CC,
336                               "%s must be %s, an instance of Unknown Class given",
337                               object_name, expected_type);
338     }
339   } else if (Z_TYPE_P(object) == IS_STRING) {
340     zend_throw_exception_ex(php_driver_invalid_argument_exception_ce, 0 TSRMLS_CC,
341                             "%s must be %s, '%Z' given",
342                             object_name, expected_type, object);
343   } else {
344     zend_throw_exception_ex(php_driver_invalid_argument_exception_ce, 0 TSRMLS_CC,
345                             "%s must be %s, %Z given",
346                             object_name, expected_type, object);
347   }
348 }
349 
PHP_INI_MH(OnUpdateLogLevel)350 PHP_INI_MH(OnUpdateLogLevel)
351 {
352   /* If TSRM is enabled then the last thread to update this wins */
353 
354   if (new_value) {
355     if (PHP5TO7_STRCMP(new_value, "CRITICAL") == 0) {
356       cass_log_set_level(CASS_LOG_DISABLED);
357     } else if (PHP5TO7_STRCMP(new_value, "ERROR") == 0) {
358       cass_log_set_level(CASS_LOG_ERROR);
359     } else if (PHP5TO7_STRCMP(new_value, "WARN") == 0) {
360       cass_log_set_level(CASS_LOG_WARN);
361     } else if (PHP5TO7_STRCMP(new_value, "INFO") == 0) {
362       cass_log_set_level(CASS_LOG_INFO);
363     } else if (PHP5TO7_STRCMP(new_value, "DEBUG") == 0) {
364       cass_log_set_level(CASS_LOG_DEBUG);
365     } else if (PHP5TO7_STRCMP(new_value, "TRACE") == 0) {
366       cass_log_set_level(CASS_LOG_TRACE);
367     } else {
368       php_error_docref(NULL TSRMLS_CC, E_NOTICE,
369                        PHP_DRIVER_NAME " | Unknown log level '%s', using 'ERROR'",
370 #if PHP_MAJOR_VERSION >= 7
371                        ZSTR_VAL(new_value));
372 #else
373                        new_value);
374 #endif
375       cass_log_set_level(CASS_LOG_ERROR);
376     }
377   }
378 
379   return SUCCESS;
380 }
381 
PHP_INI_MH(OnUpdateLog)382 PHP_INI_MH(OnUpdateLog)
383 {
384   /* If TSRM is enabled then the last thread to update this wins */
385 
386   uv_rwlock_wrlock(&log_lock);
387   if (log_location) {
388     free(log_location);
389     log_location = NULL;
390   }
391   if (new_value) {
392     if (PHP5TO7_STRCMP(new_value, "syslog") != 0) {
393       char realpath[MAXPATHLEN + 1];
394       if (VCWD_REALPATH(PHP5TO7_STRVAL(new_value), realpath)) {
395         log_location = strdup(realpath);
396       } else {
397         log_location = strdup(PHP5TO7_STRVAL(new_value));
398       }
399     } else {
400       log_location = strdup(PHP5TO7_STRVAL(new_value));
401     }
402   }
403   uv_rwlock_wrunlock(&log_lock);
404 
405   return SUCCESS;
406 }
407 
408 
PHP_GINIT_FUNCTION(php_driver)409 static PHP_GINIT_FUNCTION(php_driver)
410 {
411   uv_once(&log_once, php_driver_log_initialize);
412 
413   php_driver_globals->uuid_gen            = NULL;
414   php_driver_globals->uuid_gen_pid        = 0;
415   php_driver_globals->persistent_clusters = 0;
416   php_driver_globals->persistent_sessions = 0;
417   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_varchar);
418   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_text);
419   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_blob);
420   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_ascii);
421   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_bigint);
422   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_smallint);
423   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_counter);
424   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_int);
425   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_varint);
426   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_boolean);
427   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_decimal);
428   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_double);
429   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_float);
430   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_inet);
431   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_timestamp);
432   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_uuid);
433   PHP5TO7_ZVAL_UNDEF(php_driver_globals->type_timeuuid);
434 }
435 
PHP_GSHUTDOWN_FUNCTION(php_driver)436 static PHP_GSHUTDOWN_FUNCTION(php_driver)
437 {
438   if (php_driver_globals->uuid_gen) {
439     cass_uuid_gen_free(php_driver_globals->uuid_gen);
440   }
441   php_driver_log_cleanup();
442 }
443 
PHP_MINIT_FUNCTION(php_driver)444 PHP_MINIT_FUNCTION(php_driver)
445 {
446   REGISTER_INI_ENTRIES();
447 
448   le_php_driver_cluster_res =
449   zend_register_list_destructors_ex(NULL, php_driver_cluster_dtor,
450                                     PHP_DRIVER_CLUSTER_RES_NAME,
451                                     module_number);
452   le_php_driver_session_res =
453   zend_register_list_destructors_ex(NULL, php_driver_session_dtor,
454                                     PHP_DRIVER_SESSION_RES_NAME,
455                                     module_number);
456 
457   php_driver_define_Exception(TSRMLS_C);
458   php_driver_define_InvalidArgumentException(TSRMLS_C);
459   php_driver_define_DomainException(TSRMLS_C);
460   php_driver_define_RuntimeException(TSRMLS_C);
461   php_driver_define_TimeoutException(TSRMLS_C);
462   php_driver_define_LogicException(TSRMLS_C);
463   php_driver_define_ExecutionException(TSRMLS_C);
464   php_driver_define_ReadTimeoutException(TSRMLS_C);
465   php_driver_define_WriteTimeoutException(TSRMLS_C);
466   php_driver_define_UnavailableException(TSRMLS_C);
467   php_driver_define_TruncateException(TSRMLS_C);
468   php_driver_define_ValidationException(TSRMLS_C);
469   php_driver_define_InvalidQueryException(TSRMLS_C);
470   php_driver_define_InvalidSyntaxException(TSRMLS_C);
471   php_driver_define_UnauthorizedException(TSRMLS_C);
472   php_driver_define_UnpreparedException(TSRMLS_C);
473   php_driver_define_ConfigurationException(TSRMLS_C);
474   php_driver_define_AlreadyExistsException(TSRMLS_C);
475   php_driver_define_AuthenticationException(TSRMLS_C);
476   php_driver_define_ProtocolException(TSRMLS_C);
477   php_driver_define_ServerException(TSRMLS_C);
478   php_driver_define_IsBootstrappingException(TSRMLS_C);
479   php_driver_define_OverloadedException(TSRMLS_C);
480   php_driver_define_RangeException(TSRMLS_C);
481   php_driver_define_DivideByZeroException(TSRMLS_C);
482 
483   php_driver_define_Value(TSRMLS_C);
484   php_driver_define_Numeric(TSRMLS_C);
485   php_driver_define_Bigint(TSRMLS_C);
486   php_driver_define_Smallint(TSRMLS_C);
487   php_driver_define_Tinyint(TSRMLS_C);
488   php_driver_define_Blob(TSRMLS_C);
489   php_driver_define_Decimal(TSRMLS_C);
490   php_driver_define_Float(TSRMLS_C);
491   php_driver_define_Inet(TSRMLS_C);
492   php_driver_define_Timestamp(TSRMLS_C);
493   php_driver_define_Date(TSRMLS_C);
494   php_driver_define_Time(TSRMLS_C);
495   php_driver_define_UuidInterface(TSRMLS_C);
496   php_driver_define_Timeuuid(TSRMLS_C);
497   php_driver_define_Uuid(TSRMLS_C);
498   php_driver_define_Varint(TSRMLS_C);
499   php_driver_define_Custom(TSRMLS_C);
500   php_driver_define_Duration(TSRMLS_C);
501 
502   php_driver_define_Set(TSRMLS_C);
503   php_driver_define_Map(TSRMLS_C);
504   php_driver_define_Collection(TSRMLS_C);
505   php_driver_define_Tuple(TSRMLS_C);
506   php_driver_define_UserTypeValue(TSRMLS_C);
507 
508   php_driver_define_Core(TSRMLS_C);
509   php_driver_define_Cluster(TSRMLS_C);
510   php_driver_define_DefaultCluster(TSRMLS_C);
511   php_driver_define_ClusterBuilder(TSRMLS_C);
512   php_driver_define_Future(TSRMLS_C);
513   php_driver_define_FuturePreparedStatement(TSRMLS_C);
514   php_driver_define_FutureRows(TSRMLS_C);
515   php_driver_define_FutureSession(TSRMLS_C);
516   php_driver_define_FutureValue(TSRMLS_C);
517   php_driver_define_FutureClose(TSRMLS_C);
518   php_driver_define_Session(TSRMLS_C);
519   php_driver_define_DefaultSession(TSRMLS_C);
520   php_driver_define_SSLOptions(TSRMLS_C);
521   php_driver_define_SSLOptionsBuilder(TSRMLS_C);
522   php_driver_define_Statement(TSRMLS_C);
523   php_driver_define_SimpleStatement(TSRMLS_C);
524   php_driver_define_PreparedStatement(TSRMLS_C);
525   php_driver_define_BatchStatement(TSRMLS_C);
526   php_driver_define_ExecutionOptions(TSRMLS_C);
527   php_driver_define_Rows(TSRMLS_C);
528 
529   php_driver_define_Schema(TSRMLS_C);
530   php_driver_define_DefaultSchema(TSRMLS_C);
531   php_driver_define_Keyspace(TSRMLS_C);
532   php_driver_define_DefaultKeyspace(TSRMLS_C);
533   php_driver_define_Table(TSRMLS_C);
534   php_driver_define_DefaultTable(TSRMLS_C);
535   php_driver_define_Column(TSRMLS_C);
536   php_driver_define_DefaultColumn(TSRMLS_C);
537   php_driver_define_Index(TSRMLS_C);
538   php_driver_define_DefaultIndex(TSRMLS_C);
539   php_driver_define_MaterializedView(TSRMLS_C);
540   php_driver_define_DefaultMaterializedView(TSRMLS_C);
541   php_driver_define_Function(TSRMLS_C);
542   php_driver_define_DefaultFunction(TSRMLS_C);
543   php_driver_define_Aggregate(TSRMLS_C);
544   php_driver_define_DefaultAggregate(TSRMLS_C);
545 
546   php_driver_define_Type(TSRMLS_C);
547   php_driver_define_TypeScalar(TSRMLS_C);
548   php_driver_define_TypeCollection(TSRMLS_C);
549   php_driver_define_TypeSet(TSRMLS_C);
550   php_driver_define_TypeMap(TSRMLS_C);
551   php_driver_define_TypeTuple(TSRMLS_C);
552   php_driver_define_TypeUserType(TSRMLS_C);
553   php_driver_define_TypeCustom(TSRMLS_C);
554 
555   php_driver_define_RetryPolicy(TSRMLS_C);
556   php_driver_define_RetryPolicyDefault(TSRMLS_C);
557   php_driver_define_RetryPolicyDowngradingConsistency(TSRMLS_C);
558   php_driver_define_RetryPolicyFallthrough(TSRMLS_C);
559   php_driver_define_RetryPolicyLogging(TSRMLS_C);
560 
561   php_driver_define_TimestampGenerator(TSRMLS_C);
562   php_driver_define_TimestampGeneratorMonotonic(TSRMLS_C);
563   php_driver_define_TimestampGeneratorServerSide(TSRMLS_C);
564 
565   return SUCCESS;
566 }
567 
PHP_MSHUTDOWN_FUNCTION(php_driver)568 PHP_MSHUTDOWN_FUNCTION(php_driver)
569 {
570   /* UNREGISTER_INI_ENTRIES(); */
571 
572   return SUCCESS;
573 }
574 
PHP_RINIT_FUNCTION(php_driver)575 PHP_RINIT_FUNCTION(php_driver)
576 {
577 #define XX_SCALAR(name, value) \
578   PHP5TO7_ZVAL_UNDEF(PHP_DRIVER_G(type_##name));
579 
580   PHP_DRIVER_SCALAR_TYPES_MAP(XX_SCALAR)
581 #undef XX_SCALAR
582 
583   return SUCCESS;
584 }
585 
PHP_RSHUTDOWN_FUNCTION(php_driver)586 PHP_RSHUTDOWN_FUNCTION(php_driver)
587 {
588 #define XX_SCALAR(name, value) \
589   PHP5TO7_ZVAL_MAYBE_DESTROY(PHP_DRIVER_G(type_##name));
590 
591   PHP_DRIVER_SCALAR_TYPES_MAP(XX_SCALAR)
592 #undef XX_SCALAR
593 
594   return SUCCESS;
595 }
596 
PHP_MINFO_FUNCTION(php_driver)597 PHP_MINFO_FUNCTION(php_driver)
598 {
599   char buf[256];
600   php_info_print_table_start();
601   php_info_print_table_header(2, PHP_DRIVER_NAMESPACE " support", "enabled");
602 
603   snprintf(buf, sizeof(buf), "%d.%d.%d%s",
604            CASS_VERSION_MAJOR, CASS_VERSION_MINOR, CASS_VERSION_PATCH,
605            strlen(CASS_VERSION_SUFFIX) > 0 ? "-" CASS_VERSION_SUFFIX : "");
606   php_info_print_table_row(2, "C/C++ driver version", buf);
607 
608   snprintf(buf, sizeof(buf), "%d", PHP_DRIVER_G(persistent_clusters));
609   php_info_print_table_row(2, "Persistent Clusters", buf);
610 
611   snprintf(buf, sizeof(buf), "%d", PHP_DRIVER_G(persistent_sessions));
612   php_info_print_table_row(2, "Persistent Sessions", buf);
613 
614   php_info_print_table_end();
615 
616   DISPLAY_INI_ENTRIES();
617 }
618