php_monetdb.c
来自「这个是内存数据库的客户端」· C语言 代码 · 共 2,237 行 · 第 1/5 页
C
2,237 行
PHP_RSHUTDOWN_FUNCTION(monetdb){ /* clean up notice messages */ zend_hash_clean(&MG(notices)); zend_hash_clean(&MG(errors)); /* clean up persistent connection */ zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions TSRMLS_CC); return SUCCESS;}/* }}} *//* {{{ PHP_MINFO_FUNCTION */PHP_MINFO_FUNCTION(monetdb){ char buf[256]; /* make new Mapi struct with nonsense values in order to obtain the * Mapi version */ Mapi m = mapi_mapi("localhost", 0, "user", "pass", "lang", NULL); php_info_print_table_start(); php_info_print_table_header(2, "MonetDB Support", "enabled"); php_info_print_table_row(2, "Mapi Version", mapi_get_mapi_version(m));#ifdef HAVE_OPENSSL php_info_print_table_row(2, "SSL support", "enabled");#else php_info_print_table_row(2, "SSL support", "disabled");#endif sprintf(buf, "%ld", MG(num_persistent)); php_info_print_table_row(2, "Active Persistent Links", buf); sprintf(buf, "%ld", MG(num_links)); php_info_print_table_row(2, "Active Links", buf); php_info_print_table_end(); mapi_destroy(m); DISPLAY_INI_ENTRIES();}/* }}} *//* {{{ php_monetdb_do_connect */static void php_monetdb_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent){ char *hostname = MG(default_hostname); char *username = MG(default_username); char *password = MG(default_password); char *language = MG(default_language); char *database = NULL; int port = MG(default_port); zval **args[5]; int argc, i, connect_type = 0; smart_str str = {0}; Mconn *monetdb; argc = ZEND_NUM_ARGS(); if (argc > 7 || zend_get_parameters_array_ex(argc, args) != SUCCESS) WRONG_PARAM_COUNT; switch (argc) { case 7: /* connect type */ convert_to_long_ex(args[6]); connect_type = Z_LVAL_PP(args[6]); /* fall through */ case 6: /* database */ convert_to_string_ex(args[5]); database = Z_STRVAL_PP(args[5]); /* fall through */ case 5: /* password */ convert_to_string_ex(args[4]); password = Z_STRVAL_PP(args[4]); /* fall through */ case 4: /* username */ convert_to_string_ex(args[3]); username = Z_STRVAL_PP(args[3]); /* fall through */ case 3: /* port */ convert_to_long_ex(args[2]); port = Z_LVAL_PP(args[2]); /* fall through */ case 2: /* hostname */ convert_to_string_ex(args[1]); hostname = Z_STRVAL_PP(args[1]); /* fall through */ case 1: /* language */ convert_to_string_ex(args[0]); language = Z_STRVAL_PP(args[0]); break; } smart_str_appends(&str, "monetdb"); for (i = 0; i < ZEND_NUM_ARGS(); i++) { convert_to_string_ex(args[i]); smart_str_appendc(&str, '_'); smart_str_appendl(&str, Z_STRVAL_PP(args[i]), Z_STRLEN_PP(args[i])); } smart_str_0(&str); /* only allow persistant links if the global configuration allows it */ if (persistent && MG(allow_persistent)) { zend_rsrc_list_entry *le; /* try to find if we already have this link in our persistent list */ if (zend_hash_find(&EG(persistent_list), str.c, str.len+1, (void **) &le)==FAILURE) { /* we don't */ zend_rsrc_list_entry new_le; if (MG(max_links)!=-1 && MG(num_links)>=MG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%ld)", MG(num_links)); goto err; } if (MG(max_persistent)!=-1 && MG(num_persistent)>=MG(max_persistent)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open persistent links (%ld)", MG(num_persistent)); goto err; } /* create the link */ monetdb = mapi_connect(hostname, port, username, password, language, database); if (mapi_error(monetdb) != 0) { PHP_MONETDB_ERROR("Unable to connect to MonetDB server: %s", monetdb); mapi_disconnect(monetdb); goto err; } /* in XQuery mode, we request "tabular" seq mode */ if (strcmp(language, "xquery") == 0) { mapi_output(monetdb, "seq"); } /* hash it up */ Z_TYPE(new_le) = le_plink; new_le.ptr = monetdb; if (zend_hash_update(&EG(persistent_list), str.c, str.len+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) { goto err; } MG(num_links)++; MG(num_persistent)++; } else { /* we do already have a persistent link */ if (Z_TYPE_P(le) != le_plink) { RETURN_FALSE; } /* ensure that the link did not die */ if (MG(auto_reset_persistent) & 1) { /* need to send & get something from backend to make sure we catch MONETDB_CONNECTION_BAD everytime */ Mresult *monetdb_result; monetdb_result = mapi_query(le->ptr, "select 1;"); if (monetdb_result != NULL) mapi_close_handle(monetdb_result); } if (mapi_is_connected(le->ptr) == 0) { /* the link died */ mapi_reconnect(le->ptr); if (mapi_is_connected(le->ptr) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"MonetDB link lost, unable to reconnect"); zend_hash_del(&EG(persistent_list),str.c,str.len+1); mapi_disconnect(le->ptr); goto err; } } monetdb = (Mconn *) le->ptr; } ZEND_REGISTER_RESOURCE(return_value, monetdb, le_plink); } else { /* non persistent connection */ zend_rsrc_list_entry *index_ptr,new_index_ptr; /* first we check the hash for the hashed_details key. if it * exists, it should point us to the right offset where the * actual monetdb link sits. If it doesn't, open a new monetdb * link, add it to the resource list, and add a pointer to it * with hashed_details as the key. */ if (!(connect_type & MONETDB_CONNECT_FORCE_NEW) && zend_hash_find(&EG(regular_list),str.c,str.len+1,(void **) &index_ptr)==SUCCESS) { int type, link; void *ptr; if (Z_TYPE_P(index_ptr) != le_index_ptr) { RETURN_FALSE; } link = (int)(size_t) index_ptr->ptr; ptr = zend_list_find(link,&type); /* check if the link is still there */ if (ptr && (type==le_link || type==le_plink)) { Z_LVAL_P(return_value) = link; zend_list_addref(link); php_monetdb_set_default_link(link TSRMLS_CC); Z_TYPE_P(return_value) = IS_RESOURCE; goto cleanup; } else { zend_hash_del(&EG(regular_list),str.c,str.len+1); } } if (MG(max_links)!=-1 && MG(num_links)>=MG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%ld)", MG(num_links)); goto err; } monetdb = mapi_connect(hostname, port, username, password, language, database); if (mapi_error(monetdb) != 0) { PHP_MONETDB_ERROR("Unable to connect to MonetDB server: %s", monetdb); mapi_disconnect(monetdb); goto err; } /* add it to the list */ ZEND_REGISTER_RESOURCE(return_value, monetdb, le_link); /* add it to the hash */ new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); Z_TYPE(new_index_ptr) = le_index_ptr; if (zend_hash_update(&EG(regular_list),str.c,str.len+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) { goto err; } MG(num_links)++; } /* set notice processer: TODO, we don't have notices yet if (! MG(ignore_notices) && Z_TYPE_P(return_value) == IS_RESOURCE) { PQsetNoticeProcessor(monetdb, _php_monetdb_notice_handler, (void*)Z_RESVAL_P(return_value)); } */ php_monetdb_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC); cleanup: smart_str_free(&str); return; err: smart_str_free(&str); RETURN_FALSE;}/* }}} *//* {{{ proto resource monetdb_connect([string language [, string host [, string port [, string username [, string port [, string database [, int connect_type]]]]]]]) Open a MonetDB connection */PHP_FUNCTION(monetdb_connect){ php_monetdb_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);}/* }}} *//* {{{ proto resource monetdb_pconnect([string language [, string host [, string port [, string username [, string port [, string database [, int connect_type]]]]]]]) Open a persistent MonetDB connection */PHP_FUNCTION(monetdb_pconnect){ php_monetdb_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);}/* }}} *//* {{{ proto bool monetdb_close([resource connection]) Close a PostgreSQL connection */ PHP_FUNCTION(monetdb_close){ zval **monetdb_link = NULL; int id; Mconn *monetdb; switch (ZEND_NUM_ARGS()) { case 0: id = MG(default_link); CHECK_DEFAULT_LINK(id); break; case 1: if (zend_get_parameters_ex(1, &monetdb_link)==FAILURE) { RETURN_FALSE; } id = -1; break; default: WRONG_PARAM_COUNT; break; } if (monetdb_link == NULL && id == -1) { RETURN_FALSE; } ZEND_FETCH_RESOURCE2(monetdb, Mconn *, monetdb_link, id, "MonetDB link", le_link, le_plink); if (id==-1) { /* explicit resource number */ zend_list_delete(Z_RESVAL_PP(monetdb_link)); } if (id!=-1 || (monetdb_link && Z_RESVAL_PP(monetdb_link)==MG(default_link))) { zend_list_delete(MG(default_link)); MG(default_link) = -1; } RETURN_TRUE;}/* }}} */#define PHP_MONETDB_DBNAME 1#define PHP_MONETDB_ERROR_MESSAGE 2#define PHP_MONETDB_HOST 6#define PHP_MONETDB_VERSION 7/* {{{ php_monetdb_get_link_info */static void php_monetdb_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type){ zval **monetdb_link = NULL; int id = -1; Mconn *monetdb; switch(ZEND_NUM_ARGS()) { case 0: id = MG(default_link); CHECK_DEFAULT_LINK(id); break; case 1: if (zend_get_parameters_ex(1, &monetdb_link)==FAILURE) { RETURN_FALSE; } break; default: WRONG_PARAM_COUNT; break; } if (monetdb_link == NULL && id == -1) { RETURN_FALSE; } ZEND_FETCH_RESOURCE2(monetdb, Mconn *, monetdb_link, id, "MonetDB link", le_link, le_plink); switch(entry_type) { case PHP_MONETDB_DBNAME: Z_STRVAL_P(return_value) = mapi_get_dbname(monetdb); break; case PHP_MONETDB_ERROR_MESSAGE: { php_monetdb_notice** error; if (zend_hash_index_find(&MG(errors), (ulong)monetdb, (void **)&error) == FAILURE) { RETURN_FALSE; } if ((*error)->message == NULL) { RETURN_STRING(estrdup("(no error message)"), 1); } else { RETURN_STRINGL((*error)->message, (*error)->len, 1); } } return; case PHP_MONETDB_HOST: Z_STRVAL_P(return_value) = mapi_get_host(monetdb); break; case PHP_MONETDB_VERSION: array_init(return_value); add_assoc_string(return_value, "mapi", mapi_get_mapi_version(monetdb), 1); add_assoc_string(return_value, "mserver", mapi_get_monet_version(monetdb), 1); return; default: RETURN_FALSE; } if (Z_STRVAL_P(return_value)) { Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); Z_STRVAL_P(return_value) = (char *) estrdup(Z_STRVAL_P(return_value)); } else { Z_STRLEN_P(return_value) = 0; Z_STRVAL_P(return_value) = (char *) estrdup(""); } Z_TYPE_P(return_value) = IS_STRING;}/* }}} *//* {{{ proto string monetdb_dbname([resource connection]) Get the database name */ PHP_FUNCTION(monetdb_dbname){ php_monetdb_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_MONETDB_DBNAME);}/* }}} *//* {{{ proto string monetdb_last_error([resource connection]) Get the error message string */PHP_FUNCTION(monetdb_last_error){ php_monetdb_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_MONETDB_ERROR_MESSAGE);}/* }}} *//* {{{ proto string monetdb_host([resource connection]) Returns the host name associated with the connection */PHP_FUNCTION(monetdb_host){ php_monetdb_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_MONETDB_HOST);}/* }}} *//* {{{ proto array monetdb_version([resource connection]) Returns an array with client, protocol and server version (when available) */PHP_FUNCTION(monetdb_version){ php_monetdb_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_MONETDB_VERSION);}/* }}} *//* {{{ proto bool monetdb_ping([resource connection]) Ping database. If connection is bad, try to reconnect. */PHP_FUNCTION(monetdb_ping){ zval *monetdb_link; int id; Mconn *monetdb; if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r", &monetdb_link) == SUCCESS) { id = -1; } else { monetdb_link = NULL; id = MG(default_link); } if (monetdb_link == NULL && id == -1) { RETURN_FALSE; } ZEND_FETCH_RESOURCE2(monetdb, Mconn *, &monetdb_link, id, "MonetDB link", le_link, le_plink); /* ping connection and see if the connection is ok */ if (mapi_ping(monetdb) == 0) RETURN_TRUE; /* reset connection if it's broken */ if (mapi_reconnect(monetdb) == MOK) { RETURN_TRUE; } RETURN_FALSE;}/* }}} *//* {{{ proto resource monetdb_query([resource connection,] string query) Execute a query */PHP_FUNCTION(monetdb_query){ zval **query, **monetdb_link = NULL; int id = -1; char *myq; Mconn *monetdb; Mresult *monetdb_result; php_monetdb_result_handle *monetdb_result_h; switch(ZEND_NUM_ARGS()) { case 1: if (zend_get_parameters_ex(1, &query)==FAILURE) { RETURN_FALSE; } id = MG(default_link); CHECK_DEFAULT_LINK(id); break; case 2:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?