Ejemplo n.º 1
0
int
main(int argc, char *argv[])
{
	char buf[102];
	SQLLEN ind;
	int failed = 0;

	odbc_use_version3 = 1;
	odbc_connect();

	CHKBindCol(1, SQL_C_DEFAULT, buf, 100, &ind, "S");
	odbc_command("SELECT CONVERT(NCHAR(10), 'Pippo 123')");

	/* get data */
	memset(buf, 0, sizeof(buf));
	CHKFetch("S");

	SQLMoreResults(odbc_stmt);
	SQLMoreResults(odbc_stmt);

	odbc_disconnect();

	if (strcmp(buf, "Pippo 123 ") != 0) {
		fprintf(stderr, "Wrong results '%s'\n", buf);
		failed = 1;
	}

	return failed ? 1 : 0;
}
Ejemplo n.º 2
0
static void
Test(int use_indicator)
{
	char buf[128];
	SQLLEN ind;
	SQLLEN *pind = use_indicator ? &ind : NULL;

	strcpy(buf, "I don't exist");
	ind = strlen(buf);

	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, buf, 128, pind) != SQL_SUCCESS) {
		printf("Unable to bind parameter\n");
		exit(1);
	}

	if (SQLPrepare(Statement, (SQLCHAR *) "SELECT id, name FROM master..sysobjects WHERE name = ?", SQL_NTS) != SQL_SUCCESS) {
		printf("Unable to prepare statement\n");
		exit(1);
	}

	if (SQLExecute(Statement) != SQL_SUCCESS) {
		printf("Unable to execute statement\n");
		exit(1);
	}

	if (SQLFetch(Statement) != SQL_NO_DATA) {
		printf("Data not expected\n");
		exit(1);
	}

	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
		printf("Not expected another recordset\n");
		exit(1);
	}

	/* use same binding above */
	strcpy(buf, "sysobjects");
	ind = strlen(buf);

	if (SQLExecute(Statement) != SQL_SUCCESS) {
		printf("Unable to execute statement\n");
		exit(1);
	}

	if (SQLFetch(Statement) != SQL_SUCCESS) {
		printf("Data expected\n");
		exit(1);
	}

	if (SQLFetch(Statement) != SQL_NO_DATA) {
		printf("Data not expected\n");
		exit(1);
	}

	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
		printf("Not expected another recordset\n");
		exit(1);
	}
}
Ejemplo n.º 3
0
static void
test_params(void)
{
#define ARRAY_SIZE 2
	const rows_set_t *p;
	SQLULEN len;
	SQLUINTEGER *ids = MALLOC_N(SQLUINTEGER,ARRAY_SIZE);
	SQLLEN *id_lens = MALLOC_N(SQLLEN,ARRAY_SIZE);
	unsigned long int h, l;
	unsigned int n;

	for (n = 0; n < ARRAY_SIZE; ++n) {
		ids[n] = n;
		id_lens[n] = 0;
	}

	/* test setting just some test pointers */
	set_ipd_params1(int2ptr(0x01020304));
	check_ipd_params();
	set_ipd_params2(int2ptr(0xabcdef12));
	check_ipd_params();
	set_ipd_params3(int2ptr(0x87654321));
	check_ipd_params();

	/* now see results */
	for (p = param_set; *p != NULL; ++p) {
		odbc_reset_statement();
		len = 0xdeadbeef;
		len <<= 16;
		len <<= 16;
		len |= 12345678;

		(*p)(&len);
		check_ipd_params();

		CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S");

		odbc_command("INSERT INTO #tmp1(i) VALUES(?)");
		SQLMoreResults(odbc_stmt);
		for (n = 0; n < ARRAY_SIZE; ++n)
			SQLMoreResults(odbc_stmt);
		l = len;
		len >>= 16;
		h = len >> 16;
		l &= 0xfffffffflu;
		if (h != 0 || l != 2) {
			fprintf(stderr, "Wrong number returned in param rows high %lu low %lu\n", h, l);
			exit(1);
		}
	}

	free(ids);
	free(id_lens);
}
Ejemplo n.º 4
0
bool ODBCStatementImpl::hasNext()
{
	if (hasData())
	{
		if (!extractions().size()) 
			makeInternalExtractors();

		if (!_prepared) doPrepare();

		if (_stepCalled) 
			return _stepCalled = nextRowReady();

		makeStep();

		if (!nextRowReady())
		{
			if (hasMoreDataSets()) activateNextDataSet();
			else return false;	

			if (SQL_NO_DATA == SQLMoreResults(_stmt)) 
				return false;

			addPreparation();
			doPrepare();
			fixupExtraction();
			makeStep();
		}
		else if (Utility::isError(_nextResponse))
			checkError(_nextResponse, "SQLFetch()");

		return true;
	}

	return false;
}
Ejemplo n.º 5
0
    bool OdbcConnection::TryReadNextResult()
    {
        if (executionState == FetchRow)
        {

            SQLRETURN ret = SQLMoreResults(statement);
            if (ret == SQL_STILL_EXECUTING) 
            { 
                return false; 
            }
            if (ret == SQL_NO_DATA) 
            { 
                resultset->moreRows = false;
                statement.Free();
                executionState = Idle;
                return true;
            }
            else 
            {
                resultset->moreRows = true;
            }
            if (!SQL_SUCCEEDED(ret)) 
            { 
                statement.Throw();
            }

            executionState = CountingColumns;
        }

        return TryExecute(L"");
    }
Ejemplo n.º 6
0
bool CODBC_RPCCmd::xCheck4MoreResults()
{
//     int rc = CheckSIE(SQLMoreResults(GetHandle()),
//              "SQLMoreResults failed", 420015);
//
//     return (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS);

    switch(SQLMoreResults(GetHandle())) {
    case SQL_SUCCESS_WITH_INFO: ReportErrors();
    case SQL_SUCCESS:           return true;
    case SQL_NO_DATA:           return false;
    case SQL_ERROR:
        ReportErrors();
        {
            string err_message = "SQLMoreResults failed." + GetDbgInfo();
            DATABASE_DRIVER_ERROR( err_message, 420014 );
        }
    default:
        {
            string err_message = "SQLMoreResults failed (memory corruption suspected)." +
                GetDbgInfo();
            DATABASE_DRIVER_ERROR( err_message, 420015 );
        }
    }
}
Ejemplo n.º 7
0
static int
CheckDirtyRead(void)
{
	SQLRETURN RetCode;

	/* transaction 1 try to change a row but not commit */
	odbc_command("UPDATE test_transaction SET t = 'second' WHERE n = 1");

	SWAP_CONN();

	/* second transaction try to fetch uncommited row */
	RetCode = odbc_command2("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1", "SE");
	if (RetCode == SQL_ERROR) {
		EndTransaction(SQL_ROLLBACK);
		SWAP_CONN();
		EndTransaction(SQL_ROLLBACK);
		return 0;	/* no dirty read */
	}

	CHKFetch("S");
	CHKFetch("No");
	SQLMoreResults(odbc_stmt);
	EndTransaction(SQL_ROLLBACK);
	SWAP_CONN();
	EndTransaction(SQL_ROLLBACK);
	return 1;
}
Ejemplo n.º 8
0
NPError 
StatementObject::MoreResults(bool *retval)
{
  if (!m_hstmt) {
    NPN_SetException(this, "Statement isn't initialized");
    return NPERR_GENERIC_ERROR;
  }

  SQLRETURN rc = SQLMoreResults(m_hstmt);
  if (SQL_SUCCEEDED(rc)) {

    SQLSMALLINT cols;
    if (SQL_SUCCEEDED(SQLNumResultCols(m_hstmt, &cols)))
      m_columnCount = cols;

    if (m_columnCount > 0)
      *retval = true;
    else
      *retval = false;
    return NPERR_NO_ERROR;

  } else if (rc == SQL_NO_DATA) {
    *retval = false;
    return NPERR_NO_ERROR;

  } else {
    StoreError(SQL_HANDLE_STMT, m_hstmt);  
    return NPERR_GENERIC_ERROR;
  }
}
Ejemplo n.º 9
0
SQLRETURN unixodbc_backend_debug::do_more_results(SQLHSTMT statement_handle) const
{
	std::cout << " *DEBUG* more_results";
	auto const return_code = SQLMoreResults(statement_handle);
	std::cout << " (return code " << return_code << ")" << std::endl;
	return return_code;
}
Ejemplo n.º 10
0
bool OdbcCommand::MoveNextSet()
{
	if (!isOpen())
		return false;

	return SQL_SUCCEEDED(m_resultCode = SQLMoreResults(m_hStmt));
}
Ejemplo n.º 11
0
static void
Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, const char *expected)
{
	unsigned char out_buf[256];
	SQLLEN out_len = 0;
	SQL_NUMERIC_STRUCT *num;
	int i;

	SQLFreeStmt(Statement, SQL_UNBIND);
	SQLFreeStmt(Statement, SQL_RESET_PARAMS);

	/* execute a select to get data as wire */
	sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
	Command(Statement, sbuf);
	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
	if (SQLFetch(Statement) != SQL_SUCCESS) {
		fprintf(stderr, "Expected row\n");
		exit(1);
	}
	if (SQLFetch(Statement) != SQL_NO_DATA) {
		fprintf(stderr, "Row not expected\n");
		exit(1);
	}
	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
		fprintf(stderr, "Recordset not expected\n");
		exit(1);
	}

	/* test results */
	sbuf[0] = 0;
	switch (out_c_type) {
	case SQL_C_NUMERIC:
		num = (SQL_NUMERIC_STRUCT *) out_buf;
		sprintf(sbuf, "%d %d %d ", num->precision, num->scale, num->sign);
		i = SQL_MAX_NUMERIC_LEN;
		for (; i > 0 && !num->val[--i];);
		for (; i >= 0; --i)
			sprintf(strchr(sbuf, 0), "%02X", num->val[i]);
		break;
	case SQL_C_BINARY:
		assert(out_len >= 0);
		for (i = 0; i < out_len; ++i)
			sprintf(strchr(sbuf, 0), "%02X", (int) out_buf[i]);
		break;
	case SQL_C_CHAR:
		out_buf[sizeof(out_buf) - 1] = 0;
		sprintf(sbuf,"%u %s", (unsigned int) strlen((char *) out_buf), out_buf);
		break;
	default:
		/* not supported */
		assert(0);
		break;
	}

	if (strcmp(sbuf, expected) != 0) {
		fprintf(stderr, "Wrong result\n  Got: %s\n  Expected: %s\n", sbuf, expected);
		result = 1;
	}
}
Ejemplo n.º 12
0
static int odbc_dispatch9(void)
{
	unsigned long retval;
	PWord rval; int rtype;
	PWord arg1; int type1;
	PWord arg2; int type2;
	PWord arg3; int type3;

	PI_getan(&arg1,&type1,1);
	if (type1 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg1,type1))
			PI_FAIL;
	PI_getan(&arg2,&type2,2);
	if (type2 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg2,type2))
			PI_FAIL;
	PI_getan(&arg3,&type3,3);


	switch(arg1)
	{
		case 0:
			retval = (unsigned long) SQLMoreResults(((SQLHSTMT  ) arg2));
			break;
		case 1:
			retval = (unsigned long) SQLFreeEnv(((SQLHENV  ) arg2));
			break;
		case 2:
			retval = (unsigned long) SQLFreeConnect(((SQLHDBC  ) arg2));
			break;
		case 3:
			retval = (unsigned long) SQLFetch(((SQLHSTMT  ) arg2));
			break;
		case 4:
			retval = (unsigned long) SQLExecute(((SQLHSTMT  ) arg2));
			break;
		case 5:
			retval = (unsigned long) SQLDisconnect(((SQLHDBC  ) arg2));
			break;
		case 6:
			retval = (unsigned long) SQLCloseCursor(((SQLHSTMT  ) arg2));
			break;
		case 7:
			retval = (unsigned long) SQLCancel(((SQLHSTMT  ) arg2));
			break;
		case 8:
			retval = (unsigned long) SQLAllocEnv(((SQLHENV * ) arg2));
			break;
		default:
			PI_FAIL;
	}
	PI_makedouble(&rval,&rtype,(double) retval);
	if (PI_unify(arg3,type3,rval,rtype))
		PI_SUCCEED;
	PI_FAIL;
}
Ejemplo n.º 13
0
bool CDbStmt::Next()
{
	SQLRETURN nReturn;

	if (myDone)
		return false;

	if (myRow == -1) {
		Bind();
		if (myRow == -1) {
			myDone = true;
			if (myHSTMT && *myHSTMT)
				SQLMoreResults(*myHSTMT);
			return false;
		}
	}
	if (myBufIndex < (myRowsetSize-1)) {
		++myBufIndex;
		++myRow;
		return true;
	} else {
		if (myHSTMT) {
			smx_log(SMXLOGLEVEL_DEBUG, "fetch again with same bound memory");
			nReturn = SQLFetch(*myHSTMT);
			if (SQL_SUCCEEDED(nReturn)) {
				++myRow;
				myHasData = true;
				myBufIndex = 0;
				return true;
			} else {
				nReturn = SQLMoreResults(*myHSTMT);
				if (SQL_SUCCEEDED(nReturn)) {
					smx_log(SMXLOGLEVEL_DEBUG, "reallocate for more results");
					FreeMem();
					myRow = -1;
					return Next();
				} else
					myDone = true;
			}
		}
		return false;
	}
}
Ejemplo n.º 14
0
	void Finish() {
		if (!myDone) {
			if (myHSTMT && *myHSTMT) {
				SQLRETURN nReturn;
				do {
					nReturn = SQLMoreResults(*myHSTMT);
				} while (SQL_SUCCEEDED(nReturn));
			}
			myDone = true;
		}
	}
Ejemplo n.º 15
0
static void
NextResults(SQLRETURN expected, int line)
{
	if (SQLMoreResults(Statement) != expected) {
		if (expected == SQL_SUCCESS)
			fprintf(stderr, "Expected another recordset line %d\n", line);
		else
			fprintf(stderr, "Not expected another recordset line %d\n", line);
		exit(1);
	}
}
Ejemplo n.º 16
0
bool CDbStmt::Next()
{
	SQLRETURN nReturn;

	if (myDone)
		return false;

	if (myRow == -1) {
		Bind();
		if (myRow == -1) {
			myDone = true;
			if (myHSTMT && *myHSTMT)
				SQLMoreResults(*myHSTMT);
			return false;
		}
	}
	if (myBufIndex < (myRowsetSize-1)) {
		++myBufIndex;
		++myRow;
		return true;
	} else {
		if (myHSTMT) {
			nReturn = SQLFetch(*myHSTMT);
			if (SQL_SUCCEEDED(nReturn)) {
				myBufIndex = 0;
				++myRow;
				myHasData = true;
				return true;
			} else {
				nReturn = SQLMoreResults(*myHSTMT);
				if (SQL_SUCCEEDED(nReturn)) {
					FreeMem();
					myRow = -1;
					return Next();
				} else
					myDone = true;
			}
		}
		return false;
	}
}
Ejemplo n.º 17
0
Archivo: odbc.c Proyecto: kevinarpe/kx
K eval(K x,K y,K z){K*k;S*b,s;SQLULEN w;SQLLEN*nb;SQLINTEGER*wb;H*tb,u,t,j=0,p,m;F f;C c[128];I n=xj<0;D d=d1(n?-xj:xj);U(d)x=y;Q(z->t!=-KJ||xt!=-KS&&xt!=KC,"type")
 if(z->j)SQLSetStmtAttr(d,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER)(SQLULEN)z->j,0);
 if(xt==-KS)Q1(SQLColumns(d,(S)0,0,(S)0,0,xs,S0,(S)0,0))else{I e;K q=kpn(xG,xn);ja(&q,"\0");e=SQLExecDirect(d,q->G0,xn);r0(q);Q1(e)}
 SQLNumResultCols(d,&j);P(!j,(d0(d),knk(0)))
 b=malloc(j*SZ),tb=malloc(j*2),wb=malloc(j*SZ),nb=malloc(j*SZ),x=ktn(KS,j),y=ktn(0,j);// sqlserver: no bind past nonbind
 DO(j,Q1(SQLDescribeCol(d,(H)(i+1),c,128,&u,&t,&w,&p,&m))xS[i]=sn(c,u);
if(t>90)t-=82;
Q(t<-11||t>12,xS[i])wb[i]=ut[tb[i]=t=t>0?t:12-t]==KS&&w?w+1:wt[t];if(ut[t]==KS&&(n||!wb[i]||wb[i]>9))tb[i]=13)
 DO(j,kK(y)[i]=ktn(ut[t=tb[i]],0);if(w=wb[i])Q1(SQLBindCol(d,(H)(i+1),ct[t],b[i]=malloc(w),w,nb+i)))
 for(;SQL_SUCCEEDED(SQLFetch(d));)DO(j,k=kK(y)+i;u=ut[t=tb[i]];s=b[i];n=SQL_NULL_DATA==(int)nb[i];
if(!u)jk(k,n?ktn(ct[t]?KC:KG,0):wb[i]?kp(s):gb(d,(H)(i+1),t));
else ja(k,n?nu(u):u==KH&&wb[i]==1?(t=(H)*s,(S)&t):u==KS?(s=dtb(s,nb[i]),(S)&s):u<KD?s:u==KZ?(f=ds(s)+(vs(s+6)+*(I*)(s+12)/1e9)/8.64e4,(S)&f):(w=u==KD?ds(s):vs(s),(S)&w))) 
 if(!SQLMoreResults(d))O("more\n");DO(j,if(wb[i])free(b[i]))R free(b),free(tb),free(wb),free(nb),d0(d),xT(xD(x,y));}
Ejemplo n.º 18
0
static void print_all_results(HSTMT hstmt)
{
	int i;
	int rc = SQL_SUCCESS;
	for (i = 1; rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO; i++)
	{
		printf("--%d ", i);
		print_result(hstmt);

		rc = SQLMoreResults(hstmt);
	}
	if (rc != SQL_NO_DATA)
		CHECK_STMT_RESULT(rc, "SQLMoreResults failed", hstmt);
}
Ejemplo n.º 19
0
static int
CheckPhantom(void)
{
	SQLRETURN RetCode;

	/* transaction 2 read a row */
	SWAP_CONN();
	odbc_command("SELECT * FROM test_transaction WHERE t = 'initial'");
	SQLMoreResults(odbc_stmt);

	/* transaction 1 insert a row that match critera */
	SWAP_CONN();
	RetCode = odbc_command2("INSERT INTO test_transaction(n, t) VALUES(2, 'initial')", "SE");
	if (RetCode == SQL_ERROR) {
		EndTransaction(SQL_ROLLBACK);
		SWAP_CONN();
		EndTransaction(SQL_ROLLBACK);
		SWAP_CONN();
		return 0;	/* no dirty read */
	}
	EndTransaction(SQL_COMMIT);

	SWAP_CONN();

	/* second transaction try to fetch commited row */
	odbc_command("SELECT * FROM test_transaction WHERE t = 'initial'");

	CHKFetch("S");
	CHKFetch("S");
	CHKFetch("No");
	SQLMoreResults(odbc_stmt);
	EndTransaction(SQL_ROLLBACK);
	SWAP_CONN();
	odbc_command("DELETE test_transaction WHERE n = 2");
	EndTransaction(SQL_COMMIT);
	return 1;
}
Ejemplo n.º 20
0
static int
CheckNonrepeatableRead(void)
{
	SQLRETURN RetCode;

	/* transaction 2 read a row */
	SWAP_CONN();
	odbc_command("SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1");
	SQLMoreResults(odbc_stmt);

	/* transaction 1 change a row and commit */
	SWAP_CONN();
	RetCode = odbc_command2("UPDATE test_transaction SET t = 'second' WHERE n = 1", "SE");
	if (RetCode == SQL_ERROR) {
		EndTransaction(SQL_ROLLBACK);
		SWAP_CONN();
		EndTransaction(SQL_ROLLBACK);
		SWAP_CONN();
		return 0;	/* no dirty read */
	}
	EndTransaction(SQL_COMMIT);

	SWAP_CONN();

	/* second transaction try to fetch commited row */
	odbc_command("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");

	CHKFetch("S");
	CHKFetch("No");
	SQLMoreResults(odbc_stmt);
	EndTransaction(SQL_ROLLBACK);
	SWAP_CONN();
	odbc_command("UPDATE test_transaction SET t = 'initial' WHERE n = 1");
	EndTransaction(SQL_COMMIT);
	return 1;
}
Ejemplo n.º 21
0
int
odbc_connect(void)
{
	ODBC_BUF *odbc_buf = NULL;
	char command[512];
	const char *p;

	if (odbc_read_login_info())
		exit(1);

	if (odbc_use_version3) {
		CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env, "S");
		SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
		CHKAllocHandle(SQL_HANDLE_DBC, odbc_env, &odbc_conn, "S");
	} else {
		CHKAllocEnv(&odbc_env, "S");
		CHKAllocConnect(&odbc_conn, "S");
	}

	printf("odbctest\n--------\n\n");
	printf("connection parameters:\nserver:   '%s'\nuser:     '******'\npassword: '******'\ndatabase: '%s'\n",
	       odbc_server, odbc_user, "????" /* odbc_password */ , odbc_database);

	p = getenv("ODBC_MARS");
	if (p && atoi(p) != 0)
		SQLSetConnectAttr(odbc_conn, 1224 /*SQL_COPT_SS_MARS_ENABLED*/, (SQLPOINTER) 1 /*SQL_MARS_ENABLED_YES*/, SQL_IS_UINTEGER);
	if (odbc_set_conn_attr)
		(*odbc_set_conn_attr)();

	CHKConnect(T(odbc_server), SQL_NTS, T(odbc_user), SQL_NTS, T(odbc_password), SQL_NTS, "SI");

	CHKAllocStmt(&odbc_stmt, "S");

	sprintf(command, "use %s", odbc_database);
	printf("%s\n", command);

	CHKExecDirect(T(command), SQL_NTS, "SI");

#ifndef TDS_NO_DM
	/* unixODBC seems to require it */
	SQLMoreResults(odbc_stmt);
#endif
	ODBC_FREE();
	return 0;
}
Ejemplo n.º 22
0
int
main(int argc, char *argv[])
{
	SQLRETURN ret;
	int i;

	Connect();

	Command(Statement, "create table #timeout(i int)");
	Command(Statement, "insert into #timeout values(1)");

	for (i = 0; i < 2; ++i) {

		printf("Loop %d\n", i);

		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER));

		CHK(SQLPrepare, (Statement, (SQLCHAR*) "select * from #timeout", SQL_NTS));
		CHK(SQLExecute, (Statement));

		do {
			while ((ret=SQLFetch(Statement)) == SQL_SUCCESS)
				;
			assert(ret == SQL_NO_DATA);
		} while ((ret = SQLMoreResults(Statement)) == SQL_SUCCESS);
		assert(ret == SQL_NO_DATA);

		if (i == 0) {
			printf("Sleep 15 seconds to test if timeout occurs\n");
			sleep(15);
		}

		SQLFreeStmt(Statement, SQL_CLOSE);
		SQLFreeStmt(Statement, SQL_UNBIND);
		SQLFreeStmt(Statement, SQL_RESET_PARAMS);
		SQLCloseCursor(Statement);
	}

	Disconnect();

	return 0;
}
Ejemplo n.º 23
0
int
odbc_connect(void)
{
    char command[512];

    if (odbc_read_login_info())
        exit(1);

    if (odbc_use_version3) {
        CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env, "S");
        SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
        CHKAllocHandle(SQL_HANDLE_DBC, odbc_env, &odbc_conn, "S");
    } else {
        CHKAllocEnv(&odbc_env, "S");
        CHKAllocConnect(&odbc_conn, "S");
    }

    printf("odbctest\n--------\n\n");
    printf("connection parameters:\nserver:   '%s'\nuser:     '******'\npassword: '******'\ndatabase: '%s'\n",
           odbc_server, odbc_user, "????" /* odbc_password */ , odbc_database);

    if (odbc_set_conn_attr)
        (*odbc_set_conn_attr)();

    CHKR(SQLConnect, (odbc_conn, (SQLCHAR *) odbc_server, SQL_NTS, (SQLCHAR *) odbc_user, SQL_NTS, (SQLCHAR *) odbc_password, SQL_NTS), "SI");

    CHKAllocStmt(&odbc_stmt, "S");

    sprintf(command, "use %s", odbc_database);
    printf("%s\n", command);

    CHKExecDirect((SQLCHAR *) command, SQL_NTS, "SI");

#ifndef TDS_NO_DM
    /* unixODBC seems to require it */
    SQLMoreResults(odbc_stmt);
#endif
    return 0;
}
Ejemplo n.º 24
0
static int odbc_stmt_next_rowset(pdo_stmt_t *stmt)
{
	SQLRETURN rc;
	SQLSMALLINT colcount;
	pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;

	/* NOTE: can't guarantee that output or input/output parameters
	 * are set until this fella returns SQL_NO_DATA, according to
	 * MSDN ODBC docs */
	rc = SQLMoreResults(S->stmt);

	if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
		return 0;
	}

	free_cols(stmt, S);
	/* how many columns do we have ? */
	SQLNumResultCols(S->stmt, &colcount);
	stmt->column_count = (int)colcount;
	S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
	S->going_long = 0;

	return 1;
}
Ejemplo n.º 25
0
/*
 *  Test program to run on the connected database
 */
int
ODBC_Test ()
{
  SQLTCHAR request[4096];
  SQLTCHAR fetchBuffer[1024];
  char buf[4096];
  size_t displayWidths[MAXCOLS];
  size_t displayWidth;
  short numCols;
  short colNum;
  SQLTCHAR colName[50];
  SQLSMALLINT colType;
  SQLULEN colPrecision;
  SQLLEN colIndicator;
  SQLSMALLINT colScale;
  SQLSMALLINT colNullable;
  unsigned long totalRows;
  unsigned long totalSets;
  int i;
  SQLRETURN sts;

  while (1)
    {
      /*
       *  Ask the user for a dynamic SQL statement
       */
      printf ("\nSQL>");
      if (fgets (buf, sizeof (buf), stdin) == NULL)
	break;

#ifndef UNICODE
      strcpy ((char *) request, (char *) buf);
#else
      strcpy_A2W (request, buf);
#endif

      request[TXTLEN (request) - 1] = TEXTC ('\0');

      if (request[0] == TEXTC ('\0'))
	continue;

      /*
       *  If the user just types tables, give him a list
       */
      if (!TXTCMP (request, TEXT ("tables")))
	{
	  if (SQLTables (hstmt, NULL, 0, NULL, 0, NULL, 0,
		  NULL, 0) != SQL_SUCCESS)
	    {
	      ODBC_Errors ("SQLTables(tables)");
	      continue;
	    }
	}
      /*
       *  If the user just types qualifiers, give him a list
       */
      else if (!TXTCMP (request, TEXT ("qualifiers")))
	{
	  if (SQLTables (hstmt, TEXT ("%"), SQL_NTS, TEXT (""), 0,
		  TEXT (""), 0, TEXT (""), 0) != SQL_SUCCESS)
	    {
	      ODBC_Errors ("SQLTables(qualifiers)");
	      continue;
	    }
	}
      /*
       *  If the user just types owners, give him a list
       */
      else if (!TXTCMP (request, TEXT ("owners")))
	{
	  if (SQLTables (hstmt, TEXT (""), 0, TEXT ("%"), SQL_NTS,
		  TEXT (""), 0, TEXT (""), 0) != SQL_SUCCESS)
	    {
	      ODBC_Errors ("SQLTables(owners)");
	      continue;
	    }
	}
      /*
       *  If the user just types "types", give him a list
       */
      else if (!TXTCMP (request, TEXT ("types")))
	{
	  if (SQLTables (hstmt, TEXT (""), 0, TEXT (""), 0,
		  TEXT (""), 0, TEXT ("%"), SQL_NTS) != SQL_SUCCESS)
	    {
	      ODBC_Errors ("SQLTables(types)");
	      continue;
	    }
	}
      /*
       *  If the user just types "datatypes", give him a list
       */
      else if (!TXTCMP (request, TEXT ("datatypes")))
	{
	  if (SQLGetTypeInfo (hstmt, 0) != SQL_SUCCESS)
	    {
	      ODBC_Errors ("SQLGetTypeInfo");
	      continue;
	    }
	}
      else if (!TXTCMP (request, TEXT ("reconnect")))
	{
  	  if (ODBC_Reconnect())
	    return -1;

	  continue;
	}
#if defined (unix)
      else if (!TXTCMP (request, TEXT ("environment")))
	{
	  extern char **environ;
	  int i;

	  for (i = 0; environ[i]; i++)
	    fprintf (stderr, "%03d: [%s]\n", i, environ[i]);

	  continue;
	}
#endif
      else if (!TXTCMP (request, TEXT ("quit"))
	  || !TXTCMP (request, TEXT ("exit")))
	break;			/* If you want to quit, just say so */
      else
	{
	  /*
	   *  Prepare & Execute the statement
	   */
	  if (SQLPrepare (hstmt, (SQLTCHAR *) request,
		  SQL_NTS) != SQL_SUCCESS)
	    {
	      ODBC_Errors ("SQLPrepare");
	      continue;
	    }
	  if ((sts = SQLExecute (hstmt)) != SQL_SUCCESS)
	    {
	      ODBC_Errors ("SQLExec");

	      if (sts != SQL_SUCCESS_WITH_INFO)
		continue;
	    }
	}

      /*
       *  Loop through all the result sets
       */
      totalSets = 1;
      do
	{
	  /*
	   *  Get the number of result columns for this cursor.
	   *  If it is 0, then the statement was probably a select
	   */
	  if (SQLNumResultCols (hstmt, &numCols) != SQL_SUCCESS)
	    {
	      ODBC_Errors ("SQLNumResultCols");
	      goto endCursor;
	    }
	  if (numCols == 0)
	    {
	      SQLLEN nrows = 0;

	      SQLRowCount (hstmt, &nrows);
	      printf ("Statement executed. %ld rows affected.\n",
		  nrows > 0 ? (long) nrows : 0L);
	      goto endCursor;
	    }

	  if (numCols > MAXCOLS)
	    {
	      numCols = MAXCOLS;
	      fprintf (stderr,
		  "NOTE: Resultset truncated to %d columns.\n", MAXCOLS);
	    }

	  /*
	   *  Get the names for the columns
	   */
	  putchar ('\n');
	  for (colNum = 1; colNum <= numCols; colNum++)
	    {
	      /*
	       *  Get the name and other type information
	       */
	      if (SQLDescribeCol (hstmt, colNum,
		      (SQLTCHAR *) colName, NUMTCHAR (colName), NULL,
		      &colType, &colPrecision, &colScale,
		      &colNullable) != SQL_SUCCESS)
		{
		  ODBC_Errors ("SQLDescribeCol");
		  goto endCursor;
		}

	      /*
	       *  Calculate the display width for the column
	       */
	      switch (colType)
		{
		case SQL_VARCHAR:
		case SQL_CHAR:
		case SQL_WVARCHAR:
		case SQL_WCHAR:
		case SQL_GUID:
		  displayWidth = colPrecision;
		  break;

		case SQL_BINARY:
		  displayWidth = colPrecision * 2;
		  break;

		case SQL_LONGVARCHAR:
		case SQL_WLONGVARCHAR:
		case SQL_LONGVARBINARY:
		  displayWidth = 30;	/* show only first 30 */
		  break;

		case SQL_BIT:
		  displayWidth = 1;
		  break;

		case SQL_TINYINT:
		case SQL_SMALLINT:
		case SQL_INTEGER:
		case SQL_BIGINT:
		  displayWidth = colPrecision + 1;	/* sign */
		  break;

		case SQL_DOUBLE:
		case SQL_DECIMAL:
		case SQL_NUMERIC:
		case SQL_FLOAT:
		case SQL_REAL:
		  displayWidth = colPrecision + 2;	/* sign, comma */
		  break;

#ifdef SQL_TYPE_DATE
		case SQL_TYPE_DATE:
#endif
		case SQL_DATE:
		  displayWidth = 10;
		  break;

#ifdef SQL_TYPE_TIME
		case SQL_TYPE_TIME:
#endif
		case SQL_TIME:
		  displayWidth = 8;
		  break;

#ifdef SQL_TYPE_TIMESTAMP
		case SQL_TYPE_TIMESTAMP:
#endif
		case SQL_TIMESTAMP:
		  displayWidth = 19;
		  if (colScale > 0)
		    displayWidth = displayWidth + colScale + 1;
		  break;

		default:
		  displayWidths[colNum - 1] = 0;	/* skip other data types */
		  continue;
		}

	      if (displayWidth < TXTLEN (colName))
		displayWidth = TXTLEN (colName);
	      if (displayWidth > NUMTCHAR (fetchBuffer) - 1)
		displayWidth = NUMTCHAR (fetchBuffer) - 1;

	      displayWidths[colNum - 1] = displayWidth;

	      /*
	       *  Print header field
	       */
#ifdef UNICODE
	      printf ("%-*.*S", displayWidth, displayWidth, colName);
#else
	      printf ("%-*.*s", displayWidth, displayWidth, colName);
#endif
	      if (colNum < numCols)
		putchar ('|');
	    }
	  putchar ('\n');

	  /*
	   *  Print second line
	   */
	  for (colNum = 1; colNum <= numCols; colNum++)
	    {
	      for (i = 0; i < displayWidths[colNum - 1]; i++)
		putchar ('-');
	      if (colNum < numCols)
		putchar ('+');
	    }
	  putchar ('\n');

	  /*
	   *  Print all the fields
	   */
	  totalRows = 0;
	  while (1)
	    {
#if (ODBCVER < 0x0300)
	      int sts = SQLFetch (hstmt);
#else
	      int sts = SQLFetchScroll (hstmt, SQL_FETCH_NEXT, 1);
#endif

	      if (sts == SQL_NO_DATA_FOUND)
		break;

	      if (sts != SQL_SUCCESS)
		{
		  ODBC_Errors ("Fetch");
		  break;
		}
	      for (colNum = 1; colNum <= numCols; colNum++)
		{
		  /*
		   *  Fetch this column as character
		   */
#ifdef UNICODE
		  sts = SQLGetData (hstmt, colNum, SQL_C_WCHAR, fetchBuffer,
		      NUMTCHAR (fetchBuffer), &colIndicator);
#else
		  sts = SQLGetData (hstmt, colNum, SQL_C_CHAR, fetchBuffer,
		      NUMTCHAR (fetchBuffer), &colIndicator);
#endif
		  if (sts != SQL_SUCCESS_WITH_INFO && sts != SQL_SUCCESS)
		    {
		      ODBC_Errors ("SQLGetData");
		      goto endCursor;
		    }

		  /*
		   *  Show NULL fields as ****
		   */
		  if (colIndicator == SQL_NULL_DATA)
		    {
		      for (i = 0; i < displayWidths[colNum - 1]; i++)
			fetchBuffer[i] = TEXTC ('*');
		      fetchBuffer[i] = TEXTC ('\0');
		    }

#ifdef UNICODE
		  printf ("%-*.*S", displayWidths[colNum - 1],
		      displayWidths[colNum - 1], fetchBuffer);
#else
		  printf ("%-*.*s", displayWidths[colNum - 1],
		      displayWidths[colNum - 1], fetchBuffer);
#endif
		  if (colNum < numCols)
		    putchar ('|');
		}
	      putchar ('\n');
	      totalRows++;
	    }

	  printf ("\n result set %lu returned %lu rows.\n\n",
	      totalSets, totalRows);
	  totalSets++;
	}
      while ((sts = SQLMoreResults (hstmt)) == SQL_SUCCESS);

      if (sts == SQL_ERROR)
	ODBC_Errors ("SQLMoreResults");

    endCursor:
#if (ODBCVER < 0x0300)
      SQLFreeStmt (hstmt, SQL_CLOSE);
#else
      SQLCloseCursor (hstmt);
#endif
    }

  return 0;
}
Ejemplo n.º 26
0
int
main(int argc, char *argv[])
{
#define TEST_FILE "describecol.in"
    const char *in_file = FREETDS_SRCDIR "/" TEST_FILE;
    FILE *f;
    char buf[256];
    SQLINTEGER i;
    SQLLEN len;
    check_attr_t check_attr_p = check_attr_none;

    odbc_connect();
    odbc_command("SET TEXTSIZE 4096");

    SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);

    f = fopen(in_file, "r");
    if (!f)
        fopen(TEST_FILE, "r");
    if (!f) {
        fprintf(stderr, "error opening test file\n");
        exit(1);
    }

    line_num = 0;
    while (fgets(buf, sizeof(buf), f)) {
        char *p = buf, *cmd;

        ++line_num;

        while (isspace((unsigned char) *p))
            ++p;
        cmd = strtok(p, SEP);

        /* skip comments */
        if (!cmd || cmd[0] == '#' || cmd[0] == 0 || cmd[0] == '\n')
            continue;

        if (strcmp(cmd, "odbc") == 0) {
            int odbc3 = get_int(strtok(NULL, SEP)) == 3 ? 1 : 0;

            if (odbc_use_version3 != odbc3) {
                odbc_use_version3 = odbc3;
                odbc_disconnect();
                odbc_connect();
                odbc_command("SET TEXTSIZE 4096");
                SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
            }
        }

        /* select type */
        if (strcmp(cmd, "select") == 0) {
            const char *type = strtok(NULL, SEP);
            const char *value = strtok(NULL, SEP);
            char sql[sizeof(buf) + 40];

            SQLMoreResults(odbc_stmt);
            odbc_reset_statement();

            sprintf(sql, "SELECT CONVERT(%s, %s) AS col", type, value);

            /* ignore error, we only need precision of known types */
            check_attr_p = check_attr_none;
            if (odbc_command_with_result(odbc_stmt, sql) != SQL_SUCCESS) {
                odbc_reset_statement();
                SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
                continue;
            }

            CHKFetch("SI");
            SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
            check_attr_p = check_attr_ird;
        }

        /* set attribute */
        if (strcmp(cmd, "set") == 0) {
            const struct attribute *attr = lookup_attr(strtok(NULL, SEP));
            char *value = strtok(NULL, SEP);
            SQLHDESC desc;
            SQLRETURN ret;
            SQLINTEGER ind;

            if (!value)
                fatal("Line %u: value not defined\n", line_num);

            /* get ARD */
            SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_ROW_DESC, &desc, sizeof(desc), &ind);

            ret = SQL_ERROR;
            switch (attr->type) {
            case type_INTEGER:
                ret = SQLSetDescField(desc, 1, attr->value, int2ptr(lookup(value, attr->lookup)),
                                      sizeof(SQLINTEGER));
                break;
            case type_SMALLINT:
                ret = SQLSetDescField(desc, 1, attr->value, int2ptr(lookup(value, attr->lookup)),
                                      sizeof(SQLSMALLINT));
                break;
            case type_LEN:
                ret = SQLSetDescField(desc, 1, attr->value, int2ptr(lookup(value, attr->lookup)),
                                      sizeof(SQLLEN));
                break;
            case type_CHARP:
                ret = SQLSetDescField(desc, 1, attr->value, (SQLPOINTER) value, SQL_NTS);
                break;
            }
            if (!SQL_SUCCEEDED(ret))
                fatal("Line %u: failure not expected setting ARD attribute\n", line_num);
            check_attr_p = check_attr_ard;
        }

        /* test attribute */
        if (strcmp(cmd, "attr") == 0) {
            const struct attribute *attr = lookup_attr(strtok(NULL, SEP));
            char *expected = strtok(NULL, SEP);

            if (!expected)
                fatal("Line %u: value not defined\n", line_num);

            check_attr_p(attr, expected);
        }
    }

    fclose(f);
    odbc_disconnect();

    printf("Done.\n");
    return g_result;
}
Ejemplo n.º 27
0
static void
Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *select_sql)
{
#define ROWS 4
#define C_LEN 10

	SQLUINTEGER n[ROWS];
	char c[ROWS][C_LEN];
	SQLLEN c_len[ROWS], n_len[ROWS];

	SQLUSMALLINT statuses[ROWS];
	SQLUSMALLINT i;
	SQLULEN num_row;
	SQLHSTMT stmt2;

	/* create test table */
	odbc_command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
	odbc_command(create_sql);
	for (i = 1; i <= 6; ++i) {
		char sql_buf[80], data[10];
		memset(data, 'a' + (i - 1), sizeof(data));
		data[i] = 0;
		sprintf(sql_buf, insert_sql, data, i);
		odbc_command(sql_buf);
	}

	/* set cursor options */
	odbc_reset_statement();
	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S");
	CHKSetCursorName(T("C1"), SQL_NTS, "S");

	/* */
	CHKExecDirect(T(select_sql), SQL_NTS, "S");

	/* bind some rows at a time */
	CHKBindCol(1, SQL_C_ULONG, n, 0, n_len, "S");
	CHKBindCol(2, SQL_C_CHAR, c, C_LEN, c_len, "S");

	/* allocate an additional statement */
	CHKAllocStmt(&stmt2, "S");

	while (CHKFetchScroll(SQL_FETCH_NEXT, 0, "SNo") == SQL_SUCCESS) {
		/* print, just for debug */
		for (i = 0; i < num_row; ++i)
			printf("row %d i %d c %s\n", (int) (i + 1), (int) n[i], c[i]);
		printf("---\n");

		/* delete a row */
		i = 1;
		if (i > 0 && i <= num_row) {
			if (mssql2005)
				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE, "SI");
			else
				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE, "S");
			if (use_sql) {
				SWAP_STMT(stmt2);
				CHKPrepare(T("DELETE FROM #test WHERE CURRENT OF C1"), SQL_NTS, "S");
				CHKExecute("S");
				SWAP_STMT(stmt2);
			}
		}

		/* update another row */
		i = 2;
		if (i > 0 && i <= num_row) {
			strcpy(c[i - 1], "foo");
			c_len[i - 1] = 3;
			if (strstr(select_sql, "#a") == NULL || use_sql) {
				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "S");
			} else {
				SQLTCHAR sqlstate[6];
				SQLTCHAR msg[256];

				n[i - 1] = 321;
				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "E");

				CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, msg, ODBC_VECTOR_SIZE(msg), NULL, "S");
				if (strstr(C(msg), "Invalid column name 'c'") == NULL) {
					fprintf(stderr, "Expected message not found at line %d\n", __LINE__);
					exit(1);
				}
			}
			if (use_sql) {
				SWAP_STMT(stmt2);
				CHKPrepare(T("UPDATE #test SET c=? WHERE CURRENT OF C1"), SQL_NTS, "S");
				CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, C_LEN, 0, c[i - 1], 0, NULL, "S");
				CHKExecute("S");
				/* FIXME this is not necessary for mssql driver */
				SQLMoreResults(odbc_stmt);
				SWAP_STMT(stmt2);
			}
		}
	}

	SWAP_STMT(stmt2);
	CHKFreeStmt(SQL_DROP, "S");
	SWAP_STMT(stmt2);

	odbc_reset_statement();

	/* test values */
	CheckNoRow("IF (SELECT COUNT(*) FROM #test) <> 4 SELECT 1");
	CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 3 AND c = 'ccc') SELECT 1");
	CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 4 AND c = 'dddd') SELECT 1");
	if (strstr(select_sql, "#a") == NULL || use_sql) {
		CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 2 AND c = 'foo') SELECT 1");
		CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 6 AND c = 'foo') SELECT 1");
	}
}
Ejemplo n.º 28
0
SQLRETURN unixodbc_backend::do_more_results(SQLHSTMT statement_handle) const
{
	return SQLMoreResults(statement_handle);
}
Ejemplo n.º 29
0
static void
AllTests(void)
{
    struct tm *ltime;
    char buf[80];
    time_t curr_time;

    SQLINTEGER y, m, d;
    char date[128];

    printf("use_cursors %d exec_direct %d prepare_before %d\n", use_cursors, exec_direct, prepare_before);

    /* test some NULLs */
    NullInput(SQL_C_CHAR, SQL_VARCHAR, "VARCHAR(100)");
    NullInput(SQL_C_CHAR, SQL_LONGVARCHAR, "TEXT");
    NullInput(SQL_C_LONG, SQL_INTEGER, "INTEGER");
    NullInput(SQL_C_LONG, SQL_LONGVARCHAR, "TEXT");
    NullInput(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, "DATETIME");
    NullInput(SQL_C_FLOAT,  SQL_REAL, "FLOAT");
    NullInput(SQL_C_NUMERIC, SQL_LONGVARCHAR, "TEXT");
    if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u)
        NullInput(SQL_C_BIT, SQL_BIT, "BIT");
    NullInput(SQL_C_DOUBLE, SQL_DOUBLE, "MONEY");

    /* FIXME why should return 38 0 as precision and scale ?? correct ?? */
    precision = 18;
    TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "18 0 1 7B");
    TestOutput("DECIMAL(18,2)", "123", SQL_C_NUMERIC, SQL_DECIMAL, "18 0 1 7B");
    precision = 38;
    TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "38 0 1 7B");
    TestInput(SQL_C_LONG, "INTEGER", SQL_VARCHAR, "VARCHAR(20)", "12345");
    TestInput(SQL_C_LONG, "INTEGER", SQL_LONGVARCHAR, "TEXT", "12345");
    /*
     * MS driver behavior for output parameters is different
     * former returns "313233" while newer "333133323333"
     */
    if (odbc_driver_is_freetds())
        TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");

    only_test = 1;
    precision = 3;
    if (TestOutput("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, pack("ssssssl", 2004, 2, 24, 15, 16, 17, 0))) {
        /* FIXME our driver ignore precision for date */
        precision = 3;
        /* Some MS driver incorrectly prepare with smalldatetime*/
        if (!use_cursors || odbc_driver_is_freetds()) {
            TestOutput("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, pack("ll", 0x9497, 0xFBAA2C));
        }
        TestOutput("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, pack("ll", 0x9497, 0xFB9640));
    } else {
        TestOutput("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, pack("ssssssl", 2004, 2, 24, 15, 16, 0, 0));
    }
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34");

    /* test timestamp millisecond round off */
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.001 -> 2005-07-22 09:51:34.000");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.002 -> 2005-07-22 09:51:34.003");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.003 -> 2005-07-22 09:51:34.003");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.004 -> 2005-07-22 09:51:34.003");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.005 -> 2005-07-22 09:51:34.007");
    TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.006 -> 2005-07-22 09:51:34.007");

    /* FIXME on ms driver first SQLFetch return SUCCESS_WITH_INFO for truncation error */
    TestInput(SQL_C_TYPE_DATE, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 13:02:03 -> 2005-07-22 00:00:00");

    /* replace date information with current date */
    time(&curr_time);
    ltime = localtime(&curr_time);
    y = ltime->tm_year + 1900;
    m = ltime->tm_mon + 1;
    d = ltime->tm_mday;
    /* server concept of data can be different so try ask to server */
    odbc_command("SELECT GETDATE()");
    SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, date, sizeof(date), NULL);
    if (SQLFetch(odbc_stmt) == SQL_SUCCESS) {
        int a, b, c;
        if (sscanf(date, "%d-%d-%d", &a, &b, &c) == 3) {
            y = a;
            m = b;
            d = c;
        }
    }
    SQLFetch(odbc_stmt);
    SQLMoreResults(odbc_stmt);
    SQLFreeStmt(odbc_stmt, SQL_UNBIND);
    sprintf(buf, "2003-07-22 13:02:03 -> %04d-%02d-%02d 13:02:03", (int) y, (int) m, (int) d);
    TestInput(SQL_C_TYPE_TIME, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", buf);

    TestInput(SQL_C_FLOAT,  "FLOAT", SQL_REAL, "FLOAT", "1234.25");
    TestInput(SQL_C_DOUBLE, "REAL", SQL_REAL, "FLOAT", "-1234.25");
    TestInput(SQL_C_FLOAT,  "REAL", SQL_REAL, "FLOAT", "1234.25");
    TestInput(SQL_C_DOUBLE, "FLOAT", SQL_REAL, "FLOAT", "-1234.25");
    TestInput(SQL_C_FLOAT,  "FLOAT", SQL_FLOAT, "FLOAT", "1234.25");
    TestInput(SQL_C_DOUBLE, "REAL", SQL_FLOAT, "FLOAT", "-1234.25");
    TestInput(SQL_C_FLOAT,  "FLOAT", SQL_DOUBLE, "FLOAT", "1234.25");
    TestInput(SQL_C_DOUBLE, "REAL", SQL_DOUBLE, "FLOAT", "-1234.25");

    TestInput(SQL_C_UTINYINT, "TINYINT", SQL_TINYINT, "TINYINT", "231");

    TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_NUMERIC, "NUMERIC(20,3)", "765432.2 -> 765432");
    TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_VARCHAR, "VARCHAR(20)", "578246.234 -> 578246");
    TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_LONGVARCHAR, "TEXT", "578246.234 -> 578246");

    TestInput(SQL_C_CHAR, "VARCHAR(100)", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
    TestInput(SQL_C_CHAR, "TEXT", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
    TestInput(SQL_C_CHAR, "VARCHAR(100)", SQL_LONGVARBINARY, "IMAGE", "4145544F -> AETO");
    TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> AETO");
    TestInput(SQL_C_BINARY, "IMAGE", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> AETO");

    TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "0");
    TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "1");

    TestInput(SQL_C_DOUBLE, "MONEY", SQL_DOUBLE, "MONEY", "123.34");

    TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "1EasyTest");
    TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "TEXT", "1EasyTest");
    TestInput(SQL_C_WCHAR, "VARCHAR(10)", SQL_VARCHAR, "VARCHAR(10)", "Test 12345");
    TestInput(SQL_C_WCHAR, "VARCHAR(10)", SQL_LONGVARCHAR, "TEXT", "Test 12345");
    /* TODO use collate in syntax if available */
    TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "me\xf4");
    TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "TEXT", "me\xf4");

    precision = 6;
    /* output from char with conversions */
    TestOutput("VARCHAR(20)", "foo test", SQL_C_CHAR, SQL_VARCHAR, "6 foo te");
    /* TODO use collate in sintax if available */
    TestOutput("VARCHAR(20)", "0xf8f9", SQL_C_CHAR, SQL_VARCHAR, "2 \xf8\xf9");

    if ((odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u && odbc_tds_version() > 0x700)
            || (!odbc_db_is_microsoft() && strncmp(odbc_db_version(), "15.00.", 6) >= 0)) {
        TestOutput("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
        TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
    }
    if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "test");
        /* test for invalid stream due to truncation*/
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "01234567890");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "01234567890");
#ifdef ENABLE_DEVELOPING
        check_truncation = 1;
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "012345678901234567890");
        check_truncation = 1;
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "012345678901234567890");
#endif
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "\xa3h\xf9 -> 0xA3006800f900");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "0xA3006800f900 -> \xa3h\xf9");

        TestInput(SQL_C_LONG, "INT", SQL_WVARCHAR, "NVARCHAR(100)", "45236");
        TestInput(SQL_C_LONG, "INT", SQL_WLONGVARCHAR, "NTEXT", "45236");

        precision = 6;
        TestOutput("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "6 foo te");
        precision = 12;
        TestOutput("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "8 foo test");
        /* TODO use collate in sintax if available */
        TestOutput("NVARCHAR(20)", "0xf800f900", SQL_C_CHAR, SQL_WVARCHAR, "2 \xf8\xf9");

        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest2");
        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WLONGVARCHAR, "NTEXT", "1EasyTest2");
        use_nts = 1;
        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest3");
        use_nts = 1;
        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WLONGVARCHAR, "NTEXT", "1EasyTest3");
        TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WVARCHAR, "NVARCHAR(3)", "0xf800a300bc06");
        TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WLONGVARCHAR, "NTEXT", "0xf800a300bc06");

        TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_INTEGER, "INT", " -423785  -> -423785");

        TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
        TestInput(SQL_C_CHAR, "NTEXT", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");

        TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
        TestInput(SQL_C_BINARY, "IMAGE", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
    }
    if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x09000000u) {
        TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "VARCHAR(MAX)", "1EasyTest");
        TestInput(SQL_C_BINARY, "VARBINARY(20)", SQL_LONGVARBINARY, "VARBINARY(MAX)", "Anything will suite!");
    }
}
Ejemplo n.º 30
0
static int
TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *expected)
{
    char sbuf[1024];
    unsigned char out_buf[256];
    SQLLEN out_len = 0;
    const char *sep;

    odbc_reset_statement();

    /* build store procedure to test */
    odbc_command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
    sep = "'";
    if (strncmp(value_to_convert, "0x", 2) == 0)
        sep = "";
    sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, %s%s%s)", type, type, sep, value_to_convert, sep);
    odbc_command(sbuf);
    memset(out_buf, 0, sizeof(out_buf));

    if (use_cursors) {
        odbc_reset_statement();
        CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
        CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
    }

    /* bind parameter */
    if (exec_direct) {
        CHKBindParameter(1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
                         sizeof(out_buf), &out_len, "S");

        /* call store procedure */
        CHKExecDirect(T("{call spTestProc(?)}"), SQL_NTS, "S");
    } else {
        if (prepare_before)
            CHKPrepare(T("{call spTestProc(?)}"), SQL_NTS, "S");

        CHKBindParameter(1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
                         sizeof(out_buf), &out_len, "S");

        if (!prepare_before)
            CHKPrepare(T("{call spTestProc(?)}"), SQL_NTS, "S");

        CHKExecute("S");
    }

    /*
     * MS OBDC requires it cause first recordset is a recordset with a
     * warning caused by the way it execute RPC (via EXEC statement)
     */
    if (use_cursors && !odbc_driver_is_freetds())
        SQLMoreResults(odbc_stmt);

    /* test results */
    odbc_c2string(sbuf, out_c_type, out_buf, out_len);

    if (strcmp(sbuf, expected) != 0) {
        if (only_test) {
            odbc_command("drop proc spTestProc");
            ODBC_FREE();
            return 1;
        }
        fprintf(stderr, "Wrong result\n  Got: %s\n  Expected: %s\n", sbuf, expected);
        exit(1);
    }
    only_test = 0;
    odbc_command("drop proc spTestProc");
    ODBC_FREE();
    return 0;
}