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

📄 dblib.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		case SYBDATETIME:	return DATETIMEBIND;	case SYBDATETIME4:	return SMALLDATETIMEBIND;		case SYBDECIMAL:	return DECIMALBIND;	case SYBNUMERIC:	return NUMERICBIND;		case SYBFLT8:		return FLT8BIND;	case SYBREAL:		return REALBIND;	case SYBINT1:		return TINYBIND;	case SYBINT2:		return SMALLBIND;	case SYBINT4:		return INTBIND;	case SYBMONEY:		return MONEYBIND;	case SYBMONEY4:		return SMALLMONEYBIND;		default:		assert(0 == "no such datatype");	}		return 0;}/** \internal * dbbind() says: "Note that if varlen is 0, no padding takes place" * dbgetnull() will not pad varaddr unless varlen is positive.   * Vartype              Program Type    Padding         Terminator * -------------------  --------------  --------------  ---------- * CHARBIND             DBCHAR          blanks          none * STRINGBIND           DBCHAR          blanks          \0 * NTBSTRINGBIND        DBCHAR          none            \0 * VARYCHARBIND         DBVARYCHAR      none            none * BOUNDARYBIND         DBCHAR          none            \0 * SENSITIVITYBIND      DBCHAR          none            \0 */static RETCODEdbgetnull(DBPROCESS *dbproc, int bindtype, int varlen, BYTE* varaddr){	NULLREP *pnullrep;	tdsdump_log(TDS_DBG_FUNC, "dbgetnull(%p, %d, %d, %p)\n", dbproc, bindtype, varlen, varaddr);	CHECK_PARAMETER(dbproc, SYBENULL, FAIL);	CHECK_PARAMETER(varaddr, SYBENULL, FAIL);	CHECK_PARAMETER(!IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE, FAIL);	CHECK_PARAMETER(0 <= bindtype && bindtype < MAXBINDTYPES, SYBEBTYP, FAIL);		if (!varaddr) {		dbperror(dbproc, SYBENULP, 0, "dbgetnull", "varaddr");		return FAIL;	}		assert(dbproc->nullreps);	pnullrep = dbproc->nullreps + bindtype;		/* 	 * Fixed types: ignore varlen	 * Other types: ignore varlen if <= 0, else varlen must be >= pnullrep->len.	 */	switch (bindtype) {	case DATETIMEBIND:	case DECIMALBIND:	case FLT8BIND:	case INTBIND:	case MONEYBIND:	case NUMERICBIND:	case REALBIND:	case SMALLBIND:	case SMALLDATETIMEBIND:	case SMALLMONEYBIND:	case TINYBIND:		memcpy(varaddr, pnullrep->bindval, pnullrep->len);		return SUCCEED;	default:		if (pnullrep->bindval && (varlen <= 0 || varlen >= pnullrep->len)) {			memcpy(varaddr, pnullrep->bindval, pnullrep->len);		}	}	/* 	 * For variable-length types, nonpositive varlen indicates 	 * buffer is "big enough" but also not to pad.	 * Apply terminator (if applicable) and go home.  	 */	if (varlen <= 0) {		switch (bindtype) {		case STRINGBIND:		case NTBSTRINGBIND:			varaddr[pnullrep->len] = '\0';			/* fall thru */		case CHARBIND:		case VARYCHARBIND:			break;#if 0		case BOUNDARYBIND:		case SENSITIVITYBIND:#endif		default:			assert(!"unknown bindtype with unknown varlen");		}		return SUCCEED;	}		if (varlen < (long)pnullrep->len) {		tdsdump_log(TDS_DBG_FUNC, "dbgetnull: error: not setting varaddr(%p) because %d < %lu\n",					varaddr, varlen, (unsigned long int) pnullrep->len);		return FAIL;	} 			tdsdump_log(TDS_DBG_FUNC, "varaddr(%p) varlen %d < %lu?\n",				varaddr, varlen, (unsigned long int) pnullrep->len);	assert(varlen > 0);	/*	 * CHARBIND		Empty string (padded with blanks)	 * STRINGBIND		Empty string (padded with blanks, null-terminated)	 * BINARYBIND		Empty array (padded with zeros)	 */	varaddr += pnullrep->len;	varlen  -= pnullrep->len;	if (varlen > 0) {		switch (bindtype) {		case CHARBIND:			memset(varaddr, ' ', varlen);			break;		case STRINGBIND:			memset(varaddr, ' ', varlen);			varaddr[varlen-1] = '\0';			break;		case BINARYBIND:			memset(varaddr, 0, varlen);			break;		default:			assert(!"unknown bindtype");		}	}		return SUCCEED;}/** * \ingroup dblib_core * \brief Initialize db-lib.   * * \remarks Call this function before trying to use db-lib in any way.   * Allocates various internal structures and reads \c locales.conf (if any) to determine the default * date format.   * \retval SUCCEED normal.   * \retval FAIL cannot allocate an array of \c TDS_MAX_CONN \c TDSSOCKET pointers.   */RETCODEdbinit(void){	_dblib_err_handler = default_err_handler;	TDS_MUTEX_LOCK(&dblib_mutex);	tdsdump_log(TDS_DBG_FUNC, "dbinit(void)\n");	if (++g_dblib_ctx.ref_count != 1) {		TDS_MUTEX_UNLOCK(&dblib_mutex);		return SUCCEED;	}	/* 	 * DBLIBCONTEXT stores a list of current connections so they may be closed with dbexit() 	 */	g_dblib_ctx.connection_list = calloc(TDS_MAX_CONN, sizeof(TDSSOCKET *));	if (g_dblib_ctx.connection_list == NULL) {		tdsdump_log(TDS_DBG_FUNC, "dbinit: out of memory\n");		TDS_MUTEX_UNLOCK(&dblib_mutex);		return FAIL;	}	g_dblib_ctx.connection_list_size = TDS_MAX_CONN;	g_dblib_ctx.connection_list_size_represented = TDS_MAX_CONN;	g_dblib_ctx.login_timeout = -1;	g_dblib_ctx.query_timeout = -1;	TDS_MUTEX_UNLOCK(&dblib_mutex);	dblib_get_tds_ctx();	return SUCCEED;}/** * \ingroup dblib_core * \brief Allocate a \c LOGINREC structure.   * * \remarks A \c LOGINREC structure is passed to \c dbopen() to create a connection to the database.  * 	Does not communicate to the server; interacts strictly with library.   * \retval NULL the \c LOGINREC cannot be allocated. * \retval LOGINREC* to valid memory, otherwise.   */LOGINREC *dblogin(void){	LOGINREC *loginrec;	tdsdump_log(TDS_DBG_FUNC, "dblogin(void)\n");	if ((loginrec = malloc(sizeof(LOGINREC))) == NULL) {		dbperror(NULL, SYBEMEM, errno);		return NULL;	}	if ((loginrec->tds_login = tds_alloc_login()) == NULL) {		dbperror(NULL, SYBEMEM, errno);		free(loginrec);		return NULL;	}	/* set default values for loginrec */	tds_set_library(loginrec->tds_login, "DB-Library");	return loginrec;}/** * \ingroup dblib_core * \brief free the \c LOGINREC * */voiddbloginfree(LOGINREC * login){	tdsdump_log(TDS_DBG_FUNC, "dbloginfree(%p)\n", login);	if (login) {		tds_free_login(login->tds_login);		TDS_ZERO_FREE(login);	}}/** \internal * \ingroup dblib_internal  * \brief Set the value of a string in a \c LOGINREC structure.   * * Called by various macros to populate \a login.   * \param login the \c LOGINREC* to modify. * \param value the value to set it to.   * \param which the field to set.   * \retval SUCCEED the value was set. * \retval FAIL \c DBSETHID or other invalid \a which was tried.   */RETCODEdbsetlname(LOGINREC * login, const char *value, int which){	tdsdump_log(TDS_DBG_FUNC, "dbsetlname(%p, %s, %d)\n", login, value, which);	if( login == NULL ) {		dbperror(NULL, SYBEASNL, 0);		return FAIL;	}	switch (which) {	case DBSETHOST:		tds_set_host(login->tds_login, value);		return SUCCEED;		break;	case DBSETUSER:		tds_set_user(login->tds_login, value);		return SUCCEED;		break;	case DBSETPWD:		tds_set_passwd(login->tds_login, value);		return SUCCEED;		break;	case DBSETAPP:		tds_set_app(login->tds_login, value);		return SUCCEED;		break;	case DBSETCHARSET:		tds_set_client_charset(login->tds_login, value ? value : "");		return SUCCEED;		break;	case DBSETNATLANG:		tds_set_language(login->tds_login, value);		return SUCCEED;		break;	case DBSETHID:	default:		dbperror(NULL, SYBEASUL, 0); /* Attempt to set unknown LOGINREC field */		return FAIL;		break;	}}/** \internal * \ingroup dblib_internal * \brief Set an integer value in a \c LOGINREC structure.   * * Called by various macros to populate \a login.   * \param login the \c LOGINREC* to modify. * \param value the value to set it to.   * \param which the field to set.   * \retval SUCCEED the value was set. * \retval FAIL anything other than \c DBSETPACKET was passed for \a which.   */RETCODEdbsetllong(LOGINREC * login, long value, int which){	tdsdump_log(TDS_DBG_FUNC, "dbsetllong(%p, %ld, %d)\n", login, value, which);	switch (which) {	case DBSETPACKET:		if (0 <= value && value <= 999999) { 			tds_set_packet(login->tds_login, value);			return SUCCEED;		}		dbperror(0, SYBEBADPK, 0, (int) value, (int) login->tds_login->block_size);		return FAIL;		break;	default:		tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbsetllong() which = %d\n", which);		return FAIL;		break;	}}/** \internal * \ingroup dblib_internal * \brief Set an integer value in a \c LOGINREC structure.   * * Called by various macros to populate \a login.   * \param login the \c LOGINREC* to modify. * \param value the value to set it to.   * \param which the field to set.   * \retval SUCCEED the value was set. * \retval FAIL anything other than \c DBSETHIER was passed for \a which.   */RETCODEdbsetlshort(LOGINREC * login, int value, int which){	tdsdump_log(TDS_DBG_FUNC, "dbsetlshort(%p, %d, %d)\n", login, value, which);	switch (which) {	case DBSETHIER:	default:		tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbsetlshort() which = %d\n", which);		return FAIL;		break;	}}/** \internal * \ingroup dblib_internal * \brief Set a boolean value in a \c LOGINREC structure.   * * Called by various macros to populate \a login.   * \param login the \c LOGINREC* to modify. * \param value the value to set it to.   * \param which the field to set.  * \remark Only DBSETBCP is implemented.   * \retval SUCCEED the value was set. * \retval FAIL invalid value passed for \a which.   * \todo DBSETNOSHORT, DBSETENCRYPT, DBSETLABELED */RETCODEdbsetlbool(LOGINREC * login, int value, int which){	tdsdump_log(TDS_DBG_FUNC, "dbsetlbool(%p, %d, %d)\n", login, value, which);	switch (which) {	case DBSETBCP:		tds_set_bulk(login->tds_login, (TDS_TINYINT) value);		return SUCCEED;		break;	case DBSETNOSHORT:	case DBSETENCRYPT:	case DBSETLABELED:	default:		tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbsetlbool() which = %d\n", which);		return FAIL;		break;	}}/** * \ingroup dblib_core * \brief Set TDS version for future connections * */RETCODE dbsetlversion (LOGINREC * login, BYTE version){	tdsdump_log(TDS_DBG_FUNC, "dbsetlversion(%p, %x)\n", login, version);	if (login == NULL || login->tds_login == NULL)		return FAIL;			switch (version) {	case DBVER42:		login->tds_login->major_version = 4;		login->tds_login->minor_version = 2;		return SUCCEED;	case DBVER60:		login->tds_login->major_version = 6;		login->tds_login->minor_version = 0;		return SUCCEED;	}		return FAIL;}static voiddbstring_free(DBSTRING ** dbstrp){	DBSTRING *curr, *next;	/* tdsdump_log(TDS_DBG_FUNC, "dbstring_free(%p)\n", dbstrp); */	if (!dbstrp)		return;	curr = *dbstrp;	*dbstrp = NULL;	for (; curr; ) {		next = curr->strnext;		free(curr->strtext);		free(curr);		curr = next;	}}static RETCODEdbstring_concat(DBSTRING ** dbstrp, const char *p){	DBSTRING **strp = dbstrp;	/* tdsdump_log(TDS_DBG_FUNC, "dbstring_concat(%p, %s)\n", *dbstrp, p); */	while (*strp != NULL) {		strp = &((*strp)->strnext);	}	if ((*strp = malloc(sizeof(DBSTRING))) == NULL) {		dbperror(NULL, SYBEMEM, errno);		return FAIL;	}	(*strp)->strtotlen = strlen(p);	if (((*strp)->strtext = malloc((*strp)->strtotlen)) == NULL) {		TDS_ZERO_FREE(*strp);		dbperror(NULL, SYBEMEM, errno);		return FAIL;	}	memcpy((*strp)->strtext, p, (*strp)->strtotlen);	(*strp)->strnext = NULL;	return SUCCEED;}static RETCODEdbstring_assign(DBSTRING ** dbstrp, const char *p){	/* tdsdump_log(TDS_DBG_FUNC, "dbstring_assign(%p, %s)\n", *dbstrp, p); */	dbstring_free(dbstrp);	return dbstring_concat(dbstrp, p);}static DBINTdbstring_length(DBSTRING * dbstr){	DBINT len = 0;	DBSTRING *next;	/* tdsdump_log(TDS_DBG_FUNC, "dbstring_length(%p)\n", dbstr); */	for (next = dbstr; next != NULL; next = next->strnext) {		len += next->strtotlen;	}	return len;}static intdbstring_getchar(DBSTRING * dbstr, int i){	/* tdsdump_log(TDS_DBG_FUNC, "dbstring_getchar(%p, %d)\n", dbstr, i); */	if (dbstr == NULL) {		return -1;	}	if (i < 0) {		return -1;	}	if (i < dbstr->strtotlen) {		return dbstr->strtext[i];	}	return dbstring_getchar(dbstr->strnext, i - dbstr->strtotlen);}

⌨️ 快捷键说明

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