コード例 #1
0
ファイル: dbpivot.c プロジェクト: RQZeng/freetds
static boolean
reinit_results(TDSSOCKET * tds, size_t num_cols, const struct metadata_t meta[])
{
	TDSRESULTINFO *info;
	int i;

	assert(tds);
	assert(num_cols);
	assert(meta);
	
	tds_free_all_results(tds);
	tds->rows_affected = TDS_NO_COUNT;

	if ((info = alloc_results(num_cols)) == NULL)
		return false;

	tds_set_current_results(tds, info);
	if (tds->cur_cursor) {
		tds_free_results(tds->cur_cursor->res_info);
		tds->cur_cursor->res_info = info;
		tdsdump_log(TDS_DBG_INFO1, "set current_results to cursor->res_info\n");
	} else {
		tds->res_info = info;
		tdsdump_log(TDS_DBG_INFO1, "set current_results (%u column%s) to tds->res_info\n", (unsigned) num_cols, (num_cols==1? "":"s"));
	}

	tdsdump_log(TDS_DBG_INFO1, "setting up %u columns\n", (unsigned) num_cols);
	
	for (i = 0; i < num_cols; i++) {
		set_result_column(tds, info->columns[i], meta[i].name, &meta[i].col);
		info->columns[i]->bcp_terminator = (char*) meta[i].pacross;	/* overload available pointer */
	}
		
	if (num_cols > 0) {
		static char dashes[31] = "------------------------------";
		tdsdump_log(TDS_DBG_INFO1, " %-20s %-15s %-15s %-7s\n", "name", "size/wsize", "type/wtype", "utype");
		tdsdump_log(TDS_DBG_INFO1, " %-20s %15s %15s %7s\n", dashes+10, dashes+30-15, dashes+30-15, dashes+30-7);
	}
	for (i = 0; i < num_cols; i++) {
		TDSCOLUMN *curcol = info->columns[i];

		tdsdump_log(TDS_DBG_INFO1, " %-20s %7d/%-7d %7d/%-7d %7d\n", 
						tds_dstr_cstr(&curcol->column_name),
						curcol->column_size, curcol->on_server.column_size, 
						curcol->column_type, curcol->on_server.column_type, 
						curcol->column_usertype);
	}

#if 1
	/* all done now allocate a row for tds_process_row to use */
	if (TDS_FAILED(tds_alloc_row(info))) return false;
#endif
	return true;
}
コード例 #2
0
ファイル: util.c プロジェクト: smalinin/FreeTDS
/**
 * Set state of TDS connection, with logging and checking.
 * \param tds	  state information for the socket and the TDS protocol
 * \param state	  the new state of the connection, cf. TDS_STATE.
 * \return 	  the new state, which might not be \a state.
 */
TDS_STATE
tds_set_state(TDSSOCKET * tds, TDS_STATE state)
{
	const TDS_STATE prior_state = tds->state;
	static const char state_names[][10] = {
		"IDLE",
	        "QUERYING",
	        "PENDING",
	        "READING",
	        "DEAD"
	};
	assert(state < TDS_VECTOR_SIZE(state_names));
	assert(tds->state < TDS_VECTOR_SIZE(state_names));
	
	if (state == tds->state)
		return state;
	
	switch(state) {
		/* transition to READING are valid only from PENDING */
	case TDS_PENDING:
		if (tds->state != TDS_READING && tds->state != TDS_QUERYING) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			return tds->state;
		}
		tds->state = state;
		break;
	case TDS_READING:
		if (tds->state != TDS_PENDING) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			return tds->state;
		}
		tds->state = state;
		break;
	case TDS_IDLE:
		if (tds->state == TDS_DEAD && TDS_IS_SOCKET_INVALID(tds_get_s(tds))) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n",
				state_names[prior_state], state_names[state]);
			return tds->state;
		}
	case TDS_DEAD:
		tds->state = state;
		break;
	case TDS_QUERYING:
		CHECK_TDS_EXTRA(tds);

		if (tds->state == TDS_DEAD) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			tdserror(tds_get_ctx(tds), tds, TDSEWRIT, 0);
			break;
		} else if (tds->state != TDS_IDLE) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			tdserror(tds_get_ctx(tds), tds, TDSERPND, 0);
			break;
		}

		/* TODO check this code, copied from tds_submit_prepare */
		tds_free_all_results(tds);
		tds->rows_affected = TDS_NO_COUNT;
		tds_release_cursor(tds, tds->cur_cursor);
		tds->cur_cursor = NULL;
		tds->internal_sp_called = 0;

		tds->state = state;
		break;
	default:
		assert(0);
		break;
	}
	
	tdsdump_log(TDS_DBG_ERROR, "Changed query state from %s to %s\n", state_names[prior_state], state_names[state]);
	CHECK_TDS_EXTRA(tds);
	
	return tds->state; 
}
コード例 #3
0
ファイル: stream.c プロジェクト: RQZeng/freetds
/*
 * TDS 5 style result sets
 */
static int
read_result(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
{
	TDS_SMALLINT hdrsize;
	int pos = 0;
	int namelen;
	int col;
	TDSSOCKET *tds = pmbr->tds;
	int num_cols;
	TDSCOLUMN *curcol;
	TDSRESULTINFO *info;

	if (bytes_left(pmbr, buf, pos, maxlen, 3)) {
		*bytes_read = maxlen;
		return 0;
	}
	/* FIX ME -- endian */
	hdrsize = buf[1] + buf[2] * 256;
	pos += 3;

	/* read number of columns and allocate the columns structure */
	num_cols = buf[pos] + buf[pos+1] * 256;
	pos += 2;

	tds_free_all_results(tds);

	tds->res_info = tds_alloc_results(num_cols);
	info = pmbr->tds->res_info;

	/*
	 * loop through the columns populating COLINFO struct from
 	 * server response
	 */

	for (col = 0; col < info->num_cols; col++) {
		curcol = info->columns[col];

		namelen = buf[pos++];

		strncpy(curcol->column_name, (char *) &buf[pos], namelen);
		curcol->column_name[namelen] = '\0';
		pos += namelen;

		curcol->column_namelen = namelen;

		pos++;     /* flags */
		pos += 4;  /* user type */

		tds_set_column_type(tds->conn, curcol, (int)buf[pos]);
		switch(curcol->column_varint_size) {
			/* FIX ME - endian */
			case 2: curcol->column_size = buf[pos] + buf[pos+1]*256; break;
			case 1: curcol->column_size = buf[pos]; break;
			case 0: break;
		}
		pos+=curcol->column_varint_size;
		if (is_numeric_type(curcol->column_type))
			pos+=2;

		/* skip locale information */
		pos += buf[pos];
	}
	return tds_alloc_row(info);
}
コード例 #4
0
ファイル: stream.c プロジェクト: RQZeng/freetds
static int
read_col_name(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
{
	TDS_SMALLINT hdrsize;
	int pos = 0;
	int num_cols = 0;
	int namelen;
	struct tmp_col_struct *head = NULL, *cur = NULL, *prev;
	int col;
	TDSCOLUMN *curcol;
	TDSRESULTINFO *info;

	/* header size */
	if (bytes_left(pmbr, buf, pos, maxlen, 3)) {
		*bytes_read = maxlen;
		return 0;
	}
	/* FIXME -- endian */
	hdrsize = buf[1] + buf[2] * 256;
	pos += 3;

	for (;;) {
		prev = cur;
		cur = (struct tmp_col_struct *)
			malloc(sizeof(struct tmp_col_struct));
		cur->next = NULL;
		cur->column_name = NULL;

		if (prev)
			prev->next = cur;
		if (!head)
			head = cur;

		if (bytes_left(pmbr, buf, pos, maxlen, 1)) {
			*bytes_read = maxlen;
			free_col_struct(head);
			return 0;
		}
		namelen = buf[pos++];


		if (bytes_left(pmbr, buf, pos, maxlen, namelen)) {
			*bytes_read = maxlen;
			free_col_struct(head);
			return 0;
		}
		cur->column_name = (char *) malloc(namelen + 1);
		strncpy(cur->column_name, (char *) &buf[pos], namelen);
		cur->column_name[namelen] = '\0';

		pos += namelen;

		num_cols++;

		if (pos >= hdrsize)
			break;
	}

	tds_free_all_results(pmbr->tds);
	pmbr->tds->res_info = tds_alloc_results(num_cols);
	info = pmbr->tds->res_info;

	cur = head;

	for (col = 0; col < info->num_cols; col++) {
		curcol = info->columns[col];
		strncpy(curcol->column_name, cur->column_name, sizeof(curcol->column_name));
		/* FIXME ucs2 client and others */
		curcol->column_name[sizeof(curcol->column_name) - 1] = 0;
		curcol->column_namelen = strlen(curcol->column_name);
		prev = cur;
		cur = cur->next;
		free(prev->column_name);
		free(prev);
	}


	*bytes_read = pos;
	return 1;
}
コード例 #5
0
void TdsDatabaseLayer::FreeAllocatedResultSets()
{
  //fprintf(stderr, "In FreeAllocatedResultSets\n");
	int rc;
	int result_type;
  /* */
	//while ((rc = tds_process_tokens(m_pDatabase, &result_type, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCEED)
	//while ((rc = tds_process_tokens(m_pDatabase, &result_type, NULL, TDS_RETURN_ROW|TDS_TOKEN_RESULTS|TDS_RETURN_COMPUTE)) == TDS_SUCCEED)
	while ((rc = tds_process_tokens(m_pDatabase, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCEED)
  {
		switch (result_type)
    {
		case TDS_DONE_RESULT:
		case TDS_DONEPROC_RESULT:
		case TDS_DONEINPROC_RESULT:
		case TDS_STATUS_RESULT:
			break;
		case TDS_ROWFMT_RESULT:
		case TDS_COMPUTEFMT_RESULT:
		case TDS_DESCRIBE_RESULT:
			break;
    case TDS_ROW_RESULT:
			//fprintf(stderr, "Warning (%d):  TdsDatabaseLayer query should not return results.  Type: %d\n", result_type, result_type);
      if (m_pDatabase->current_results && m_pDatabase->current_results->num_cols > 0)
      {
  			while (tds_process_tokens(m_pDatabase, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW) == TDS_SUCCEED)
        {
		  	  //fprintf(stderr, "Warning:  TdsDatabaseLayer TDS_ROW_RESULT query should not return results.  Type: %d\n", result_type);
			    if (result_type != TDS_ROW_RESULT)
			      break;
 
    			if (!m_pDatabase->current_results)
	      		continue;
		  	}
      }
      if (m_pDatabase != NULL)
        tds_free_all_results(m_pDatabase);
      return;
			break;
		default:
			//fprintf(stderr, "Error:  TdsDatabaseLayer query should not return results.  Type: %d\n", result_type);
			return;
      //break;
		}
	}
 /* 
			while (tds_process_tokens(m_pDatabase, &result_type, NULL, TDS_TOKEN_RESULTS) == TDS_SUCCEED) {
				switch (result_type) {
				case TDS_ROWFMT_RESULT:
					break;
				case TDS_ROW_RESULT:
					while (tds_process_tokens(m_pDatabase, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW) == TDS_SUCCEED) {
						if (result_type != TDS_ROW_RESULT)
							break;
 
						if (!m_pDatabase->current_results)
							continue;
 
						TDSCOLUMN* col = m_pDatabase->current_results->columns[0];
						int ctype = tds_get_conversion_type(col->column_type, col->column_size);

						unsigned char* src = col->column_data;
						int srclen = col->column_cur_size;
 
            CONV_RESULT dres;
						tds_convert(m_pDatabase->tds_ctx, ctype, (TDS_CHAR *) src, srclen, SYBINT4, &dres);
						int optionval = dres.i;
					}
					break;
				default:
					break;
				}
			}
 */

  // Make sure to clean up after ourselves
  if (m_pDatabase != NULL)
    tds_free_all_results(m_pDatabase);

	if (rc == TDS_FAIL)
  {
    ThrowDatabaseException();
		//fprintf(stderr, "tds_process_tokens() returned TDS_FAIL\n");
		return;
	}
  else if (rc != TDS_NO_MORE_RESULTS)
  {
    ThrowDatabaseException();
		//fprintf(stderr, "tds_process_tokens() unexpected return\n");
		return;
	}
}
コード例 #6
0
void TdsPreparedStatement::FreeAllocatedResultSets()
{
  //fprintf(stderr, "In FreeAllocatedResultSets\n");
	int rc;
	int result_type;
	while ((rc = tds_process_tokens(m_pDatabase, &result_type, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCEED)
  {
		switch (result_type)
    {
		case TDS_DONE_RESULT:
		case TDS_DONEPROC_RESULT:
		case TDS_DONEINPROC_RESULT:
			/* ignore possible spurious result (TDS7+ send it) */
		case TDS_STATUS_RESULT:
			break;
		case TDS_ROWFMT_RESULT:
		case TDS_COMPUTEFMT_RESULT:
		case TDS_DESCRIBE_RESULT:
			break;
    case TDS_ROW_RESULT:
			//fprintf(stderr, "Warning:  TdsPreparedStatement query should not return results.  Type: %d\n", result_type);
      if (m_pDatabase->current_results && m_pDatabase->current_results->num_cols > 0)
      {
  			while (tds_process_tokens(m_pDatabase, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW) == TDS_SUCCEED)
        {
		  	  //fprintf(stderr, "Warning:  TdsPreparedStatement TDS_ROW_RESULT query should not return results.  Type: %d\n", result_type);
			    if (result_type != TDS_ROW_RESULT)
			      break;
 
    			if (!m_pDatabase->current_results)
	      		continue;
		  	}
      }
      return;
			break;
		default:
			//fprintf(stderr, "Error:  TdsPreparedStatement query should not return results.  Type: %d\n", result_type);
			return;
      //break;
		}
	}

  // Clean up after ourselves
  if (m_pDatabase != NULL)
    tds_free_all_results(m_pDatabase);

	if (rc == TDS_FAIL)
  {
		//fprintf(stderr, "tds_process_tokens() returned TDS_FAIL\n");
    SetErrorInformationFromDatabaseLayer();
    ThrowDatabaseException();
		return;
	}
  else if (rc != TDS_NO_MORE_RESULTS)
  {
		//fprintf(stderr, "tds_process_tokens() unexpected return\n");
    SetErrorInformationFromDatabaseLayer();
    ThrowDatabaseException();
		return;
	}
}
コード例 #7
0
ファイル: util.c プロジェクト: DougBeck/freetds
/**
 * Set state of TDS connection, with logging and checking.
 * \param tds	  state information for the socket and the TDS protocol
 * \param state	  the new state of the connection, cf. TDS_STATE.
 * \return 	  the new state, which might not be \a state.
 */
TDS_STATE
tds_set_state(TDSSOCKET * tds, TDS_STATE state)
{
	TDS_STATE prior_state;
	static const char state_names[][8] = {
		"IDLE",
	        "WRITING",
	        "SENDING",
	        "PENDING",
	        "READING",
	        "DEAD"
	};
	assert(state < TDS_VECTOR_SIZE(state_names));
	assert(tds->state < TDS_VECTOR_SIZE(state_names));

	prior_state = tds->state;
	if (state == prior_state)
		return state;

	switch(state) {
	case TDS_PENDING:
		if (prior_state == TDS_READING || prior_state == TDS_WRITING) {
			tds->state = TDS_PENDING;
			tds_mutex_unlock(&tds->wire_mtx);
			break;
		}
		tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n",
						state_names[prior_state], state_names[state]);
		break;
	case TDS_READING:
		/* transition to READING are valid only from PENDING */
		if (tds_mutex_trylock(&tds->wire_mtx))
			return tds->state;
		if (tds->state != TDS_PENDING) {
			tds_mutex_unlock(&tds->wire_mtx);
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			break;
		}
		tds->state = state;
		break;
	case TDS_SENDING:
		if (prior_state != TDS_READING && prior_state != TDS_WRITING) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n",
				state_names[prior_state], state_names[state]);
			break;
		}
		if (tds->state == TDS_READING) {
			/* TODO check this code, copied from tds_submit_prepare */
			tds_free_all_results(tds);
			tds->rows_affected = TDS_NO_COUNT;
			tds_release_cursor(&tds->cur_cursor);
			tds_release_cur_dyn(tds);
			tds->current_op = TDS_OP_NONE;
		}

		tds_mutex_unlock(&tds->wire_mtx);
		tds->state = state;
		break;
	case TDS_IDLE:
		if (prior_state == TDS_DEAD && TDS_IS_SOCKET_INVALID(tds_get_s(tds))) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n",
				state_names[prior_state], state_names[state]);
			break;
		}
	case TDS_DEAD:
		if (prior_state == TDS_READING || prior_state == TDS_WRITING)
			tds_mutex_unlock(&tds->wire_mtx);
		tds->state = state;
		break;
	case TDS_WRITING:
		CHECK_TDS_EXTRA(tds);

		if (tds_mutex_trylock(&tds->wire_mtx))
			return tds->state;

		if (tds->state == TDS_DEAD) {
			tds_mutex_unlock(&tds->wire_mtx);
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			tdserror(tds_get_ctx(tds), tds, TDSEWRIT, 0);
			break;
		} else if (tds->state != TDS_IDLE && tds->state != TDS_SENDING) {
			tds_mutex_unlock(&tds->wire_mtx);
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			tdserror(tds_get_ctx(tds), tds, TDSERPND, 0);
			break;
		}

		if (tds->state == TDS_IDLE) {
			/* TODO check this code, copied from tds_submit_prepare */
			tds_free_all_results(tds);
			tds->rows_affected = TDS_NO_COUNT;
			tds_release_cursor(&tds->cur_cursor);
			tds_release_cur_dyn(tds);
			tds->current_op = TDS_OP_NONE;
		}

		tds->state = state;
		break;
	default:
		assert(0);
		break;
	}

	state = tds->state;

	tdsdump_log(TDS_DBG_ERROR, "Changed query state from %s to %s\n", state_names[prior_state], state_names[state]);
	CHECK_TDS_EXTRA(tds);

	return state;
}