📄 ii.c
字号:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ingres II: Unable to connect to database (%s)", db); RETURN_FALSE; } link = (II_LINK *) malloc(sizeof(II_LINK)); link->connHandle = connParm.co_connHandle; link->tranHandle = NULL; link->stmtHandle = NULL; link->fieldCount = 0; link->descriptor = NULL; link->autocommit = 0; /* hash it up */ Z_TYPE(new_le) = le_ii_plink; new_le.ptr = link; if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length + 1, (void *) &new_le, sizeof(list_entry), NULL) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ingres II: Unable to hash (%s)", hashed_details); free(link); efree(hashed_details); RETURN_FALSE; } IIG(num_persistent)++; IIG(num_links)++; } else { /* already open persistent connection */ if (Z_TYPE_P(le) != le_ii_plink) { efree(hashed_details); RETURN_FALSE; } /* here we should ensure that the link did not die */ /* unable to figure out the right way to do this */ /* maybe does the api handle the reconnection transparently ? */ link = (II_LINK *) le->ptr; /* Unfortunetaly NO !!!*/ /* Ingres api doesn't reconnect */ /* Have to reconnect if cleaning function has flagged link as broken */ if (link->connHandle == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Ingres II: Broken link (%s),reconnect", db); /* Recreate the link */ connParm.co_genParm.gp_callback = NULL; connParm.co_genParm.gp_closure = NULL; connParm.co_target = db; connParm.co_username = user; connParm.co_password = pass; connParm.co_timeout = -1; /* no timeout */ connParm.co_connHandle = NULL; connParm.co_tranHandle = NULL; IIapi_connect(&connParm); if (!ii_sync(&(connParm.co_genParm)) || ii_success(&(connParm.co_genParm)) == II_FAIL) { efree(hashed_details); php_error_docref(NULL TSRMLS_CC, E_WARNING,"Ingres II: Unable to connect to database (%s)", db); RETURN_FALSE; } link->connHandle = connParm.co_connHandle; link->tranHandle = NULL; link->stmtHandle = NULL; link->fieldCount = 0; link->descriptor = NULL; link->autocommit = 0; } } ZEND_REGISTER_RESOURCE(return_value, link, le_ii_plink); } else { /* non persistent */ 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 link sits. * if it doesn't, open a new link, add it to the resource list, * and add a pointer to it with hashed_details as the key. */ if (zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length + 1, (void **) &index_ptr) == SUCCESS) { int type; void *ptr; if (Z_TYPE_P(index_ptr) != le_index_ptr) { RETURN_FALSE; } link = (II_LINK *) index_ptr->ptr; ptr = zend_list_find((int) link, &type); /* check if the link is still there */ if (ptr && (type == le_ii_link || type == le_ii_plink)) { zend_list_addref((int) link); Z_LVAL_P(return_value) = (int) link; php_ii_set_default_link((int) link TSRMLS_CC); Z_TYPE_P(return_value) = IS_RESOURCE; efree(hashed_details); return; } else { zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length + 1); } } if (IIG(max_links) != -1 && IIG(num_links) >= IIG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ingres II: Too many open links (%d)", IIG(num_links)); efree(hashed_details); RETURN_FALSE; } /* create the link */ connParm.co_genParm.gp_callback = NULL; connParm.co_genParm.gp_closure = NULL; connParm.co_target = db; connParm.co_username = user; connParm.co_password = pass; connParm.co_timeout = -1; /* -1 is no timeout */ connParm.co_connHandle = NULL; connParm.co_tranHandle = NULL; IIapi_connect(&connParm); if (!ii_sync(&(connParm.co_genParm)) || ii_success(&(connParm.co_genParm)) == II_FAIL) { efree(hashed_details); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ingres II: Unable to connect to database (%s)", db); RETURN_FALSE; } link = (II_LINK *) malloc(sizeof(II_LINK)); link->connHandle = connParm.co_connHandle; link->tranHandle = NULL; link->stmtHandle = NULL; link->fieldCount = 0; link->descriptor = NULL; link->autocommit = 0; /* add it to the list */ ZEND_REGISTER_RESOURCE(return_value, link, le_ii_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), hashed_details, hashed_details_length + 1, (void *) &new_index_ptr, sizeof(list_entry), NULL) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ingres II: Unable to hash (%s)", hashed_details); free(link); efree(hashed_details); RETURN_FALSE; } IIG(num_links)++; } efree(hashed_details); php_ii_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);}/* {{{ proto resource ingres_connect([string database [, string username [, string password]]]) Open a connection to an Ingres II database the syntax of database is [node_id::]dbname[/svr_class] */PHP_FUNCTION(ingres_connect){ php_ii_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto resource ingres_pconnect([string database [, string username [, string password]]]) Open a persistent connection to an Ingres II database the syntax of database is [node_id::]dbname[/svr_class] */PHP_FUNCTION(ingres_pconnect){ php_ii_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ proto bool ingres_close([resource link]) Close an Ingres II database connection */PHP_FUNCTION(ingres_close){ zval **link = NULL; int link_id = -1; II_LINK *ii_link; switch (ZEND_NUM_ARGS()) { case 0: link_id = IIG(default_link); break; case 1: if (zend_get_parameters_ex(1, &link) == FAILURE) { RETURN_FALSE; } link_id = -1; break; default: WRONG_PARAM_COUNT; break; } ZEND_FETCH_RESOURCE2(ii_link, II_LINK *, link, link_id, "Ingres II Link", le_ii_link, le_ii_plink); /* Call the clean function synchronously here */ /* Otherwise we have to wait for request shutdown */ /* This way we can reuse the link in the same script */ _ai_clean_ii_plink(ii_link TSRMLS_CC); if (link_id == -1) { /* explicit resource number */ zend_list_delete(Z_RESVAL_PP(link)); } if (link_id != -1 || (link && Z_RESVAL_PP(link) == IIG(default_link))) { zend_list_delete(IIG(default_link)); IIG(default_link) = -1; } RETURN_TRUE;}/* }}} *//* {{{ proto bool ingres_query(string query [, resource link]) Send a SQL query to Ingres II *//* This should go into the documentation *//* Unsupported query types: - close - commit - connect - disconnect - get dbevent - prepare to commit - rollback - savepoint - set autocommit - <all cursor related queries> (look for dedicated functions instead) */PHP_FUNCTION(ingres_query){ zval **query, **link; int argc; int link_id = -1; II_LINK *ii_link; IIAPI_QUERYPARM queryParm; IIAPI_GETDESCRPARM getDescrParm; argc = ZEND_NUM_ARGS(); if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &query, &link) == FAILURE) { WRONG_PARAM_COUNT; } if (argc < 2) { link_id = php_ii_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); } ZEND_FETCH_RESOURCE2(ii_link, II_LINK *, link, link_id, "Ingres II Link", le_ii_link, le_ii_plink); convert_to_string_ex(query); /* if there's already an active statement, close it */ if (ii_link->stmtHandle && _close_statement(ii_link)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ingres II: Unable to close statement !!"); RETURN_FALSE; } /* send the query */ queryParm.qy_genParm.gp_callback = NULL; queryParm.qy_genParm.gp_closure = NULL; queryParm.qy_connHandle = ii_link->connHandle; queryParm.qy_tranHandle = ii_link->tranHandle; queryParm.qy_stmtHandle = NULL; queryParm.qy_queryType = IIAPI_QT_QUERY; queryParm.qy_parameters = FALSE; queryParm.qy_queryText = Z_STRVAL_PP(query); IIapi_query(&queryParm); ii_sync(&(queryParm.qy_genParm)); if (ii_success(&(queryParm.qy_genParm)) == II_FAIL) { RETURN_FALSE; } /* store transaction and statement handles */ ii_link->tranHandle = queryParm.qy_tranHandle; ii_link->stmtHandle = queryParm.qy_stmtHandle; /* get description of results */ getDescrParm.gd_genParm.gp_callback = NULL; getDescrParm.gd_genParm.gp_closure = NULL; getDescrParm.gd_stmtHandle = ii_link->stmtHandle; IIapi_getDescriptor(&getDescrParm); ii_sync(&(getDescrParm.gd_genParm)); if (ii_success(&(getDescrParm.gd_genParm)) == II_FAIL) { RETURN_FALSE; } /* store the results */ ii_link->fieldCount = getDescrParm.gd_descriptorCount; ii_link->descriptor = getDescrParm.gd_descriptor; RETURN_TRUE;}/* }}} *//* {{{ proto int ingres_num_rows([resource link]) Return the number of rows affected/returned by the last query *//* Warning : don't call ingres_num_rows() before ingres_fetch_xx(), or ingres_fetch_xx() wouldn't find any data */PHP_FUNCTION(ingres_num_rows){ zval **link; int argc; int link_id = -1; II_LINK *ii_link; IIAPI_GETQINFOPARM getQInfoParm; argc = ZEND_NUM_ARGS(); if (argc > 1 || zend_get_parameters_ex(argc, &link) == FAILURE) { WRONG_PARAM_COUNT; } if (argc < 1) { link_id = php_ii_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); } ZEND_FETCH_RESOURCE2(ii_link, II_LINK *, link, link_id, "Ingres II Link", le_ii_link, le_ii_plink); /* get number of affected rows */ getQInfoParm.gq_genParm.gp_callback = NULL; getQInfoParm.gq_genParm.gp_closure = NULL; getQInfoParm.gq_stmtHandle = ii_link->stmtHandle; IIapi_getQueryInfo(&getQInfoParm); ii_sync(&(getQInfoParm.gq_genParm)); if (ii_success(&(getQInfoParm.gq_genParm)) == II_FAIL) { RETURN_FALSE; } /* return the result */ if (getQInfoParm.gq_mask & IIAPI_GQ_ROW_COUNT) { RETURN_LONG(getQInfoParm.gq_rowCount); } else { RETURN_LONG(0); }}/* }}} *//* {{{ proto int ingres_num_fields([resource link]) Return the number of fields returned by the last query */PHP_FUNCTION(ingres_num_fields){ zval **link; int argc; int link_id = -1; II_LINK *ii_link; argc = ZEND_NUM_ARGS(); if (argc > 1 || zend_get_parameters_ex(argc, &link) == FAILURE) { WRONG_PARAM_COUNT; } if (argc < 1) { link_id = php_ii_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); } ZEND_FETCH_RESOURCE2(ii_link, II_LINK *, link, link_id, "Ingres II Link", le_ii_link, le_ii_plink); RETURN_LONG(ii_link->fieldCount);}/* }}} */#define II_FIELD_INFO_NAME 1#define II_FIELD_INFO_TYPE 2#define II_FIELD_INFO_NULLABLE 3#define II_FIELD_INFO_LENGTH 4#define II_FIELD_INFO_PRECISION 5#define II_FIELD_INFO_SCALE 6/* Return information about a field in a query result*/static void php_ii_field_info(INTERNAL_FUNCTION_PARAMETERS, int info_type){ zval **idx, **link; int argc; int link_id = -1; char *name, *fun_name; int index; II_LINK *ii_link; argc = ZEND_NUM_ARGS(); if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &idx, &link) == FAILURE) { WRONG_PARAM_COUNT; } if (argc < 2) { link_id = php_ii_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); } ZEND_FETCH_RESOURCE2(ii_link, II_LINK *, link, link_id, "Ingres II Link", le_ii_link, le_ii_plink); convert_to_long_ex(idx); index = Z_LVAL_PP(idx); if (index < 1 || index > ii_link->fieldCount) { switch (info_type) { case II_FIELD_INFO_NAME: fun_name = "ii_field_name"; break; case II_FIELD_INFO_TYPE: fun_name = "ii_field_type"; break; case II_FIELD_INFO_NULLABLE: fun_name = "ii_field_nullable"; break; case II_FIELD_INFO_LENGTH: fun_name = "ii_field_length"; break; case II_FIELD_INFO_PRECISION: fun_name = "ii_field_precision"; break; case II_FIELD_INFO_SCALE: fun_name = "ii_field_scale"; break; default: fun_name = "foobar"; break; } php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ingres II: %s() called with wrong index (%d)", fun_name, index); RETURN_FALSE; } switch (info_type) { case II_FIELD_INFO_NAME: name = php_ii_field_name(ii_link, index TSRMLS_CC); if (name == NULL) { RETURN_FALSE; } RETURN_STRING(name, 1); break; case II_FIELD_INFO_TYPE: switch ((ii_link->descriptor[index - 1]).ds_dataType) { case IIAPI_BYTE_TYPE: RETURN_STRING("IIAPI_BYTE_TYPE", 1); case IIAPI_CHA_TYPE: RETURN_STRING("IIAPI_CHA_TYPE", 1); case IIAPI_CHR_TYPE: RETURN_STRING("IIAPI_CHR_TYPE", 1); case IIAPI_DEC_TYPE: RETURN_STRING("IIAPI_DEC_TYPE", 1); case IIAPI_DTE_TYPE: RETURN_STRING("IIAPI_DTE_TYPE", 1); case IIAPI_FLT_TYPE: RETURN_STRING("IIAPI_FLT_TYPE", 1); case IIAPI_INT_TYPE: RETURN_STRING("IIAPI_INT_TYPE", 1); case IIAPI_LOGKEY_TYPE: RETURN_STRING("IIAPI_LOGKEY_TYPE", 1); case IIAPI_LBYTE_TYPE: RETURN_STRING("IIAPI_LBYTE_TYPE", 1); case IIAPI_LVCH_TYPE: RETURN_STRING("IIAPI_LVCH_TYPE", 1); case IIAPI_MNY_TYPE: RETURN_STRING("IIAPI_MNY_TYPE", 1); case IIAPI_TABKEY_TYPE: RETURN_STRING("IIAPI_TABKEY_TYPE", 1); case IIAPI_TXT_TYPE: RETURN_STRING("IIAPI_TXT_TYPE", 1); case IIAPI_VBYTE_TYPE: RETURN_STRING("IIAPI_VBYTE_TYPE", 1); case IIAPI_VCH_TYPE: RETURN_STRING("IIAPI_VCH_TYPE", 1); default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ingres II: Unknown Ingres data type"); RETURN_FALSE; break; } break; case II_FIELD_INFO_NULLABLE: if ((ii_link->descriptor[index - 1]).ds_nullable) { RETURN_TRUE; } else { RETURN_FALSE; } break; case II_FIELD_INFO_LENGTH: RETURN_LONG((ii_link->descriptor[index - 1]).ds_length); break; case II_FIELD_INFO_PRECISION: RETURN_LONG((ii_link->descriptor[index - 1]).ds_precision); break; case II_FIELD_INFO_SCALE: RETURN_LONG((ii_link->descriptor[index - 1]).ds_scale); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -