php_monetdb.c

来自「这个是内存数据库的客户端」· C语言 代码 · 共 2,237 行 · 第 1/5 页

C
2,237
字号
/* }}} *//* {{{ proto int monetdb_affected_rows(resource result)   Returns the number of affected tuples */PHP_FUNCTION(monetdb_affected_rows){	php_monetdb_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_MONETDB_CMD_TUPLES);}/* }}} *//* {{{ proto string pg_last_notice(resource connection)   Returns the last notice set by the backend */PHP_FUNCTION(monetdb_last_notice) {	zval *monetdb_link;	Mconn *monet_conn;	int id = -1;	php_monetdb_notice **notice;		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r",							  &monetdb_link) == FAILURE) {		return;	}	/* Just to check if user passed valid resource */	ZEND_FETCH_RESOURCE2(monet_conn, Mconn *, &monetdb_link, id, "MonetDB link", le_link, le_plink);	if (zend_hash_index_find(&MG(notices), Z_RESVAL_P(monetdb_link), (void **)&notice) == FAILURE) {		RETURN_FALSE;	}	RETURN_STRINGL((*notice)->message, (*notice)->len, 1);}/* }}} */#define PHP_MONETDB_FIELD_NAME 1#define PHP_MONETDB_FIELD_TABLE 2#define PHP_MONETDB_FIELD_TYPE 3/* {{{ php_monetdb_get_field_info */static void php_monetdb_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type){	zval **result, **field;	Mresult *monetdb_result;	php_monetdb_result_handle *monetdb_result_h;		if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &result, &field)==FAILURE) {		WRONG_PARAM_COUNT;	}		ZEND_FETCH_RESOURCE(monetdb_result_h, php_monetdb_result_handle *, result, -1, "MonetDB result", le_result);	monetdb_result = monetdb_result_h->result;	convert_to_long_ex(field);		if (Z_LVAL_PP(field) < 0 || Z_LVAL_PP(field) >= mapi_get_field_count(monetdb_result)) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified");		RETURN_FALSE;	}		switch (entry_type) {		case PHP_MONETDB_FIELD_NAME:			Z_STRVAL_P(return_value) = mapi_get_name(monetdb_result, Z_LVAL_PP(field));			Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));			Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value),Z_STRLEN_P(return_value));			Z_TYPE_P(return_value) = IS_STRING;		break;		case PHP_MONETDB_FIELD_TABLE:			Z_STRVAL_P(return_value) = mapi_get_table(monetdb_result, Z_LVAL_PP(field));			Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));			Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value),Z_STRLEN_P(return_value));			Z_TYPE_P(return_value) = IS_STRING;		break;		case PHP_MONETDB_FIELD_TYPE:			Z_STRVAL_P(return_value) = mapi_get_type(monetdb_result, Z_LVAL_PP(field));			Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));			Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value),Z_STRLEN_P(return_value));			Z_TYPE_P(return_value) = IS_STRING;		break;		default:			RETURN_FALSE;	}}/* }}} *//* {{{ proto string monetdb_field_name(resource result, int field_number)   Returns the name of the field */PHP_FUNCTION(monetdb_field_name){	php_monetdb_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_MONETDB_FIELD_NAME);}/* }}} *//* {{{ proto string monetdb_field_table(resource result, int field_number)   Returns the name of the table field belongs to */PHP_FUNCTION(monetdb_field_table){	php_monetdb_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_MONETDB_FIELD_TABLE);}/* }}} *//* {{{ proto string monetdb_field_type(resource result, int field_number)   Returns the type of the field */PHP_FUNCTION(monetdb_field_type){	php_monetdb_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_MONETDB_FIELD_TYPE);}/* }}} *//* {{{ proto int monetdb_field_num(resource result, string field_name)   Returns the field number of the named field */PHP_FUNCTION(monetdb_field_num){	zval **result, **field;	Mresult *monetdb_result;	php_monetdb_result_handle *monetdb_result_h;	int i;	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &result, &field)==FAILURE) {		WRONG_PARAM_COUNT;	}		ZEND_FETCH_RESOURCE(monetdb_result_h, php_monetdb_result_handle *, result, -1, "MonetDB result", le_result);	monetdb_result = monetdb_result_h->result;		convert_to_string_ex(field);	for (i = 0; i < mapi_get_field_count(monetdb_result); i++) {		if (strcmp(mapi_get_name(monetdb_result, i), Z_STRVAL_PP(field)) == 0)		{			Z_LVAL_P(return_value) = i;			Z_TYPE_P(return_value) = IS_LONG;			break;		}	}	RETURN_FALSE;}/* }}} *//* {{{ proto mixed monetdb_fetch_result(resource result, [int row_number,] mixed field_name)   Returns values from a result identifier */PHP_FUNCTION(monetdb_fetch_result){	zval **result, **row, **field=NULL;	Mresult *monetdb_result;	php_monetdb_result_handle *monetdb_result_h;	int field_offset, monetdb_row;	char *data;		if ((ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &result, &row, &field)==FAILURE) &&	    (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &result, &field)==FAILURE)) {		WRONG_PARAM_COUNT;	}		ZEND_FETCH_RESOURCE(monetdb_result_h, php_monetdb_result_handle *, result, -1, "MonetDB result", le_result);	monetdb_result = monetdb_result_h->result;	if (ZEND_NUM_ARGS() == 2) {		if (monetdb_result_h->row < 0)			monetdb_result_h->row = 0;		monetdb_row = monetdb_result_h->row;		if (monetdb_row >= mapi_get_row_count(monetdb_result)) {			RETURN_FALSE;		}	} else {		convert_to_long_ex(row);		monetdb_row = Z_LVAL_PP(row);		if (monetdb_row < 0 || monetdb_row >= mapi_get_row_count(monetdb_result)) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on MonetDB result index %ld",							Z_LVAL_PP(row), Z_LVAL_PP(result));			RETURN_FALSE;		}	}	switch(Z_TYPE_PP(field)) {		case IS_STRING: {			int i;			field_offset = -1;			for (i = 0; i < mapi_get_field_count(monetdb_result); i++) {				if (strcmp(mapi_get_name(monetdb_result, i), Z_STRVAL_PP(field)) == 0)				{					field_offset = i;					break;				}			}		} break;		default:			convert_to_long_ex(field);			field_offset = Z_LVAL_PP(field);			break;	}	if (field_offset<0 || field_offset>=mapi_get_field_count(monetdb_result)) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified");		RETURN_FALSE;	}	/* get the data in the field */	if (mapi_seek_row(monetdb_result, monetdb_row, MAPI_SEEK_SET) != MOK) {		PHP_MONETDB_ERROR_RESULT("Can't jump to row: %s", monetdb_result_h);		RETURN_FALSE;	}	if (mapi_fetch_row(monetdb_result) == 0 &&			 mapi_error(monetdb_result_h->conn) != 0)	{		PHP_MONETDB_ERROR("Can't get row: %s", monetdb_result_h->conn);		RETURN_FALSE;	}	data = mapi_fetch_field(monetdb_result, field_offset);	if (data == NULL) {		if (mapi_error(monetdb_result_h->conn) != 0) {			PHP_MONETDB_ERROR("Can't fetch field: %s", monetdb_result_h->conn);			RETURN_FALSE;		}		Z_TYPE_P(return_value) = IS_NULL;	} else {		Z_STRVAL_P(return_value) = estrndup(data, strlen(data));		Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));		Z_TYPE_P(return_value) = IS_STRING;	}}/* }}} *//* {{{ void php_monetdb_fetch_hash */static void php_monetdb_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int into_object){	zval            *result, *zrow = NULL;	Mresult         *monetdb_result;	php_monetdb_result_handle *monetdb_result_h;	int             i, num_fields, monetdb_row, use_row;	long            row = -1;	char            *element, *field_name;	uint            element_len;	zval            *ctor_params = NULL;	zend_class_entry *ce = NULL;	if (into_object) {		char *class_name;		int class_name_len;		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z!sz", &result, &zrow, &class_name, &class_name_len, &ctor_params) == FAILURE) {			return;			}		if (ZEND_NUM_ARGS() < 3) {			ce = zend_standard_class_def;		} else {			ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);		}		if (!ce) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);			return;		}		result_type = MONETDB_ASSOC;	} else {		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z!l", &result, &zrow, &result_type) == FAILURE) {			return;		}	}	if (zrow == NULL) {		row = -1;	} else {		convert_to_long(zrow);		row = Z_LVAL_P(zrow);	}	use_row = ZEND_NUM_ARGS() > 1 && row != -1;	if (!(result_type & MONETDB_BOTH)) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type");		RETURN_FALSE;	}		ZEND_FETCH_RESOURCE(monetdb_result_h, php_monetdb_result_handle *, &result, -1, "MonetDB result", le_result);	monetdb_result = monetdb_result_h->result;	if (use_row) { 		monetdb_row = row;		monetdb_result_h->row = monetdb_row;		if (monetdb_row < 0 || monetdb_row >= mapi_get_row_count(monetdb_result)) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on MonetDB result index %ld",							row, Z_LVAL_P(result));			RETURN_FALSE;		}	} else {		/* If 2nd param is NULL, use internal row counter to access next row */		monetdb_row = monetdb_result_h->row;		if (monetdb_row < 0 || monetdb_row >= mapi_get_row_count(monetdb_result)) {			RETURN_FALSE;		}		monetdb_result_h->row++;	}	array_init(return_value);	for (i = 0, num_fields = mapi_get_field_count(monetdb_result); i < num_fields; i++) {		/* get the data in the field */		if (mapi_seek_row(monetdb_result, monetdb_row, MAPI_SEEK_SET) != MOK) {			PHP_MONETDB_ERROR_RESULT("Can't jump to row: %s", monetdb_result_h);			RETURN_FALSE;		}		if (mapi_fetch_row(monetdb_result) == 0 &&				mapi_error(monetdb_result_h->conn) != 0)		{			PHP_MONETDB_ERROR("Can't get row: %s", monetdb_result_h->conn);			RETURN_FALSE;		}		element = mapi_fetch_field(monetdb_result, i);		if (element == NULL) {			if (mapi_error(monetdb_result_h->conn) != 0) {				PHP_MONETDB_ERROR("Can't fetch field: %s", monetdb_result_h->conn);				RETURN_FALSE;			}			if (result_type & MONETDB_NUM) {				add_index_null(return_value, i);			}			if (result_type & MONETDB_ASSOC) {				field_name = mapi_get_name(monetdb_result, i);				add_assoc_null(return_value, field_name);			}		} else {			char *data;			int data_len;			int should_copy=0;			element_len = strlen(element);			data = safe_estrndup(element, element_len);			data_len = element_len;			if (result_type & MONETDB_NUM) {				add_index_stringl(return_value, i, data, data_len, should_copy);				should_copy=1;			}			if (result_type & MONETDB_ASSOC) {				field_name = mapi_get_name(monetdb_result, i);				add_assoc_stringl(return_value, field_name, data, data_len, should_copy);			}		}	}	if (into_object) {		zval dataset = *return_value;		zend_fcall_info fci;		zend_fcall_info_cache fcc;		zval *retval_ptr; 			object_and_properties_init(return_value, ce, NULL);		zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);			if (ce->constructor) {			fci.size = sizeof(fci);			fci.function_table = &ce->function_table;			fci.function_name = NULL;			fci.symbol_table = NULL;			fci.object_pp = &return_value;			fci.retval_ptr_ptr = &retval_ptr;			if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {				if (Z_TYPE_P(ctor_params) == IS_ARRAY) {					HashTable *ht = Z_ARRVAL_P(ctor_params);					Bucket *p;						fci.param_count = 0;					fci.params = emalloc(sizeof(zval*) * ht->nNumOfElements);					p = ht->pListHead;					while (p != NULL) {						fci.params[fci.param_count++] = (zval**)p->pData;						p = p->pListNext;					}				} else {					/* Two problems why we throw exceptions here: PHP is					 * typeless and hence passing one argument that's					 * not an array could be by mistake and the other					 * way round is possible, too. The single value is					 * an array. Also we'd have to make that one					 * argument passed by reference.					 */					zend_throw_exception(zend_exception_get_default(), "Parameter ctor_params must be an array", 0 TSRMLS_CC);					return;				}			} else {				fci.param_count = 0;				fci.params = NULL;			}			fci.no_separation = 1;			fcc.initialized = 1;			fcc.function_handler = ce->constructor;			fcc.calling_scope = EG(scope);			fcc.object_pp = &return_value;					if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {				zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);			} else {				if (retval_ptr) {					zval_ptr_dtor(&retval_ptr);				}			}			if (fci.params) {				efree(fci.params);			}		} else if (ctor_params) {			zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);		}	}}/* }}} *//* {{{ proto array monetdb_fetch_row(resource result [, int row [, int result_type]])   Get a row as an enumerated array */ PHP_FUNCTION(monetdb_fetch_row){	php_monetdb_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MONETDB_NUM, 0);}/* }}} *//* {{{ proto array monetdb_fetch_assoc(resource result [, int row])   Fetch a row as an assoc array */PHP_FUNCTION(monetdb_fetch_assoc){	/* monetdb_fetch_assoc() is added from PHP 4.3.0. It should raise	 * error, when there is 3rd parameter */	if (ZEND_NUM_ARGS() > 2)		WRONG_PARAM_COUNT;	php_monetdb_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MONETDB_ASSOC, 0);}/* }}} *//* {{{ proto array monetdb_fetch_array(resource result [, int row [, int result_type]])   Fetch a row as an array */PHP_FUNCTION(monetdb_fetch_array){	php_monetdb_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MONETDB_BOTH, 0);}/* }}} *//* {{{ proto object monetdb_fetch_object(resource result [, int row [, string class_name [, NULL|array ctor_params]]])   Fetch a row as an object */PHP_FUNCTION(monetdb_fetch_object){	/* monetdb_fetch_object() allowed result_type used to be. 3rd parameter	   must be allowed for compatibility */	php_monetdb_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MONETDB_ASSOC, 1);}/* }}} *//* {{{ proto bool monetdb_result_seek(resource result, int offset)   Set internal row offset */PHP_FUNCTION(monetdb_result_seek)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?