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 + -
显示快捷键?