⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i18n.c

📁 sybase数据库ct library的开发,使用了所以有函数
💻 C
📖 第 1 页 / 共 2 页
字号:
			*/
			ex_error("DoCommand: ct_results() returned unexpected result type");
			return CS_FAIL;
		}
	}

	/*
	** We're done processing results. Let's check the
	** return value of ct_results() to see if everything
	** went ok.
	*/
	switch ((int)retcode)
	{
		case CS_END_RESULTS:
			/*
			** Everything went fine.
			*/
			break;

		case CS_FAIL:
			/*
			** Something went wrong.
			*/
			ex_error("DoCommand: ct_results() failed");
			return retcode;

		default:
			/*
			** We got an unexpected return value.
			*/
			ex_error("DoCommand: ct_results() returned unexpected result code");
			return retcode;
	}

	/*
	** Drop our command structure
	*/
	if ((retcode = ct_cmd_drop(cmd)) != CS_SUCCEED)
	{
                ex_error("DoCommand: ct_cmd_drop() failed");
                return retcode;
	}

	return retcode;
}

/*
** FetchData()
**
** Type of function:
** 	International example program internal api
** 
** Purpose:
** 	This function processes fetchable results sets. The results include:
**
**		CS_ROW_RESULT
**		CS_CURSOR_RESULT 
**		CS_PARAM_RESULT 
**		CS_STATUS_RESULT 
**		CS_COMPUTE_RESULT 
**
**	Since the Client-Library result model has been unified, the same
**	apis are used for each of the above result types.
**
**	One caveat is the processing of CS_COMPUTE_RESULTs. The name field
**	sent from the server is typically zero length. To display a meaningful
**	header, the aggregate compute operator name should be found for the
**	column, and that name used instead. The compute example program has
**	code which demonstrates this.
**
**	This routine is essentially the same as the utility function
**	ex_fetch_data(), with modifications to support MY_MONEY_CHAR_TYPE
**	datatypes. If the user installed function had replaced the Sybase
**	money to char conversion routine, this function would not be
**	needed.
**
** Parameters:
**	cmd - Pointer to command structure
**
** Return:
**	CS_MEM_ERROR	If an memory allocation failed.
**	CS_SUCCEED	If the data was displayed.
**	CS_FAIL		If no columns were present.
** 	<retcode>	Result of the Client-Library function if a failure was
**			returned.
**
*/

CS_STATIC CS_RETCODE CS_INTERNAL
FetchData(cmd)
CS_COMMAND	*cmd;
{
	CS_RETCODE		retcode;
	CS_INT			num_cols;
	CS_INT			i;
	CS_INT			j;
	CS_INT			row_count = 0;
	CS_INT			rows_read;
	CS_INT			disp_len;
	CS_DATAFMT		*datafmt;
	EX_COLUMN_DATA		*coldata;

	/*
	** Find out how many columns there are in this result set.
	*/
	retcode = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
	if (retcode != CS_SUCCEED)
	{
		ex_error("FetchData: ct_res_info() failed");
		return retcode;
	}

	/*
	** Make sure we have at least one column
	*/
	if (num_cols <= 0)
	{
		ex_error("FetchData: ct_res_info() returned zero columns");
		return CS_FAIL;
	}

	/*
	** Our program variable, called 'coldata', is an array of 
	** EX_COLUMN_DATA structures. Each array element represents
	** one column.  Each array element will re-used for each row.
	**
	** First, allocate memory for the data element to process.
	*/
	coldata = (EX_COLUMN_DATA *)malloc(num_cols * sizeof (EX_COLUMN_DATA));
	if (coldata == NULL)
	{
		ex_error("FetchData: malloc() failed");
		return CS_MEM_ERROR;
	}

	datafmt = (CS_DATAFMT *)malloc(num_cols * sizeof (CS_DATAFMT));
	if (datafmt == NULL)
	{
		ex_error("FetchData: malloc() failed");
		free(coldata);
		return CS_MEM_ERROR;
	}

	/*
	** Loop through the columns getting a description of each one
	** and binding each one to a program variable.
	**
	** We're going to bind each column to a character string; 
	** this will show how conversions from server native datatypes
	** to strings can occur via bind.
	**
	** We're going to use the same datafmt structure for both the describe
	** and the subsequent bind.
	**
	** If an error occurs within the for loop, a break is used to get out
	** of the loop and the data that was allocated is free'd before
	** returning.
	*/
	for (i = 0; i < num_cols; i++)
	{
		/*
		** Get the column description.  ct_describe() fills the
		** datafmt parameter with a description of the column.
		*/
		retcode = ct_describe(cmd, (i + 1), &datafmt[i]);
		if (retcode != CS_SUCCEED)
		{
			ex_error("FetchData: ct_describe() failed");
			break;
		}

		/*
		** update the datafmt structure to indicate that we want the
		** results in a null terminated character string.
		**
		** First, update datafmt.maxlength to contain the maximum
		** possible length of the column. To do this, call
		** ex_display_len() to determine the number of bytes needed
		** for the character string representation, given the
		** datatype described above.  Add one for the null
		** termination character.
		*/
		
		/*
		** Set datatype and format to tell bind we want things
		** converted to null terminated strings
		*/
		if (datafmt[i].datatype == CS_MONEY_TYPE)
		{
			datafmt[i].maxlength = 30;
			datafmt[i].datatype = MY_MONEY_CHAR_TYPE;
			datafmt[i].format   = CS_FMT_NULLTERM;
		}
		else
		{
			datafmt[i].maxlength = ex_display_dlen(&datafmt[i]) + 1;
			datafmt[i].datatype = CS_CHAR_TYPE;
			datafmt[i].format   = CS_FMT_NULLTERM;
		}

		/*
		** Allocate memory for the column string
		*/
		coldata[i].value = (CS_CHAR *)malloc(datafmt[i].maxlength);
		if (coldata[i].value == NULL)
		{
			ex_error("FetchData: malloc() failed");
			retcode = CS_MEM_ERROR;
			break;
		}

		/*
		** Now bind.
		*/
		retcode = ct_bind(cmd, (i + 1), &datafmt[i],
				coldata[i].value, &coldata[i].valuelen,
				(CS_SMALLINT *)&coldata[i].indicator);
		if (retcode != CS_SUCCEED)
		{
			ex_error("FetchData: ct_bind() failed");
			break;
		}
	}
	if (retcode != CS_SUCCEED)
	{
		for (j = 0; j < i; j++)
		{
			free(coldata[j].value);
		}
		free(coldata);
		free(datafmt);
		return retcode;
	}

	/*
	** Display column header
	*/
	ex_display_header(num_cols, datafmt);

	/*
	** Fetch the rows.  Loop while ct_fetch() returns CS_SUCCEED or 
	** CS_ROW_FAIL
	*/
	while (((retcode = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
			&rows_read)) == CS_SUCCEED) || (retcode == CS_ROW_FAIL))
	{
		/*
		** Increment our row count by the number of rows just fetched.
		*/
		row_count = row_count + rows_read;

		/*
		** Check if we hit a recoverable error.
		*/
		if (retcode == CS_ROW_FAIL)
		{
			fprintf(stdout, "Error on row %d.\n", row_count);
			fflush(stdout);
		}

/*
** NOTE: There is a bug with cs_setnull() and user defined types (btsid
**	 45825) To work around this bug, code has been added to display
**	 a value of "NULL" whenever the column indicator is set to
**	 CS_NULLDATA. Since this example should demonstrate the
**	 cs_setnull() functionality that is available, the code has been
**	 conditionally #if'd with the following define. Once the bug has
**	 been fixed, this example should be updated.
*/
#define EX_BTSID_45825	1

		/*
		** We have a row.  Loop through the columns displaying the
		** column values.
		*/
		for (i = 0; i < num_cols; i++)
		{	  
			/*
			** Display the column value.
			**
			** NOTE: See EX_BTSID_45825 note above
			*/
#if EX_BTSID_45825
			if (coldata[i].indicator == CS_NULLDATA)
			{
				fprintf(stdout, "NULL");
				disp_len = datafmt[i].maxlength;
				disp_len -= strlen("NULL");
			}
			else
			{
				fprintf(stdout, "%s", coldata[i].value);
				disp_len = datafmt[i].maxlength;
				disp_len -= coldata[i].valuelen - 1;
			}
			fflush(stdout);

			/*
			** If not last column, Print out spaces between this
			** column and next one. 
			*/
			if (i != num_cols - 1)
			{
				for (j = 0; j < disp_len; j++)
				{
					fputc(' ', stdout);
				}
			}
#else /* EX_BTSID_45825 */
			fprintf(stdout, "%s", coldata[i].value);
			fflush(stdout);

			/*
			** If not last column, Print out spaces between this
			** column and next one. 
			*/
			if (i != num_cols - 1)
			{
				disp_len = ex_display_dlen(&datafmt[i]);
				disp_len -= coldata[i].valuelen - 1;
				for (j = 0; j < disp_len; j++)
				{
					fputc(' ', stdout);
				}
			}
#endif /* EX_BTSID_45825 */
		} 
		fprintf(stdout, "\n");
		fflush(stdout);
	}

	/*
	** Free allocated space.
	*/
	for (i = 0; i < num_cols; i++)
	{
		free(coldata[i].value);
	}
	free(coldata);
	free(datafmt);

	/*
	** We're done processing rows.  Let's check the final return
	** value of ct_fetch().
	*/
	switch ((int)retcode)
	{
		case CS_END_DATA:
			/*
			** Everything went fine.
			*/
			fprintf(stdout, MSG(MSG_ROW_DONE));
			fflush(stdout);
			retcode = CS_SUCCEED;
			break;

		case CS_FAIL:
			/*
			** Something terrible happened.
			*/
			ex_error("FetchData: ct_fetch() failed");
			return retcode;
			/*NOTREACHED*/
			break;

		default:
			/*
			** We got an unexpected return value.
			*/
			ex_error("FetchData: ct_fetch() returned an expected retcode");
			return retcode;
			/*NOTREACHED*/
			break;

	}

	return retcode;
}

/*
** MyMoneyToChar()
**
** Type of function:
** 	Installed conversion function for international example program
**
** Purpose:
**	This function does a crude attempt at supporting multiple monetary
**	formats. 
**	
**	Note that this routine may be called from interrupt level. This
**	means that the any code within this routine must be interrupt safe.
**
** Parameters:
**	context - Pointer to context structure
**	srcfmt	- Pointer to source datafmt structure.
**	srcdata	- Pointer to source data buffer.
**	destfmt	- Pointer to destination datafmt structure.
**	destdata - Pointer to destination data buffer.
**	destlen	- Pointer to length variable (might be NULL).
**
** Return:
**	CS_SUCCEED	If conversion was successful.
**	CS_EOVERFLOW	If destination buffer is too small.
** 	<retcode>	Result of the Client-Library function if a failure
**			was returned.
**
*/

CS_STATIC CS_RETCODE CS_INTERNAL
MyMoneyToChar(context, srcfmt, srcdata, destfmt, destdata, destlen)
CS_CONTEXT 	*context;
CS_DATAFMT 	*srcfmt;
CS_VOID 	*srcdata;
CS_DATAFMT 	*destfmt;
CS_VOID 	*destdata;
CS_INT 		*destlen;
{
	CS_RETCODE	retcode;
	CS_RETCODE	convcode;
	CS_DATAFMT	tmpfmt;
	CS_FLOAT	flt;
	CS_CHAR		locbuf[EX_MAXSTRINGLEN];
	CS_CHAR		tmpbuf[EX_MAXSTRINGLEN];

	/*
	** First, convert it to float. Be careful when calling conversion
	** routines from within a conversion routine, since recursion
	** might occur (e.g. float->int calling float->char and
	** float->char calling float->int would spin forever).
	*/
	memset(&tmpfmt, 0, sizeof(tmpfmt));
	tmpfmt.datatype = CS_FLOAT_TYPE;
	retcode = cs_convert(context, srcfmt, srcdata, &tmpfmt, &flt, NULL);
	if (retcode != CS_SUCCEED)
	{
		ex_error("MyMoneyToChar: cs_convert() failed");
		return retcode;
	}

	/*
	** Get the language defined for the destination locale. Using
	** this approach allows multiple locales to be supported within
	** one application.
	**
	** Another approach that can be used is to store multiple
	** monetary values within one table, differentiating them with a
	** unique usertype field in the database. They can then be
	** displayed based on the usertype. To determine the usertype for
	** the column in the database, look at the srcfmt "usertype"
	** field.
	*/
	retcode = cs_locale(context, CS_GET, destfmt->locale, CS_SYB_LANG,
				locbuf, CS_SIZEOF(locbuf), NULL);
	if (retcode != CS_SUCCEED)
	{
		ex_error("MyMoneyToChar: cs_locale(CS_GET) failed");
		return retcode;
	}

	/*
	** Based on Sybase language name, do conversion.
	*/
	switch ((int)LookupLanguage(locbuf))
	{
	    case M_FRENCH:
		sprintf(tmpbuf, "FF %-d,%02d", (int)flt,
			(int)((flt - (int)flt + .005) * 100));
	        break;

	    case M_GERMAN:
		sprintf(tmpbuf, "DM %-d,%02d", (int)flt,
			(int)((flt - (int)flt + .005) * 100));
	        break;

	    case M_ENGLISH:
		sprintf(tmpbuf, "$ %-.2f", flt);
	        break;

	    case M_UNKNOWN:
		sprintf(tmpbuf, "?? %-.2f", flt);
	        break;
	}

	/*
	** Fill in dest if there is room. Note that the destlen value
	** should contain all the data written to the buffer, including
	** the null terminator.
	*/
	if (destfmt->maxlength > strlen(tmpbuf))
	{
		strcpy(destdata, tmpbuf);
		if (destlen != NULL)
		{
			*destlen = strlen(tmpbuf) + 1;
		}
		convcode = CS_SUCCEED;
	}
	else
	{
		convcode = CS_EOVERFLOW;
	}

	return convcode;
}

/*
** LookupLanguage(lang)
**
** Type of function:
** 	International example program internal api
**
** Purpose:
**	This function will return a language define based on the
**	character string passed in. It assumes the input string is a
**	Sybase language string found in locales.dat.
**	
** Parameters:
**	lang	- Pointer to string
**
** Return:
**	M_ENGLISH	- If english is to be used
**	M_GERMAN	- If german is to be used
**	M_FRENCH	- If french is to be used
**	M_UNKNOWN	- If language is not known
*/

CS_STATIC CS_INT CS_INTERNAL
LookupLanguage(lang)
CS_CHAR	*lang;
{
	CS_INT		retlang;

	if (strcmp(lang, "french") == 0)
	{
		retlang = M_FRENCH;
	}
	else if (strcmp(lang, "german") == 0)
	{
		retlang = M_GERMAN;
	}
	else if (strcmp(lang, "us_english") == 0)
	{
		retlang = M_ENGLISH;
	}
	else
	{
		retlang = M_UNKNOWN;
	}

	return retlang;
}

⌨️ 快捷键说明

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