Esempio n. 1
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");
	}
}
Esempio n. 2
0
static void Test(void)
{
#define ROWS 5
	struct data_t {
		SQLINTEGER i;
		SQLLEN ind_i;
		char c[20];
		SQLLEN ind_c;
	} data[ROWS];
	SQLUSMALLINT statuses[ROWS];
	SQLLEN num_row;

	odbc_reset_statement();

	/* this should not fail or return warnings */
	if (use_cursors) {
		CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0, "S");
		CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0, "S");
	}
	CHKPrepare(T("SELECT c, i FROM #cursor6_test"), SQL_NTS, "S");
	CHKExecute("S");
	CHKSetStmtAttr(SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, statuses, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S");
	if (bind_all)
		CHKBindCol(1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c, "S");
	CHKBindCol(2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i, "S");

#define FILL(s, n) do { \
	int _n; for (_n = 0; _n < sizeof(s)/sizeof(s[0]); ++_n) s[_n] = n; \
} while(0)
	FILL(statuses, 9876);
	num_row = -3;
	data[0].i = (SQLINTEGER) 0xdeadbeef;
	data[1].i = (SQLINTEGER) 0xdeadbeef;
	if (normal_fetch)
		CHKFetch("S");
	else
		CHKFetchScroll(SQL_FETCH_NEXT, 0, "S");

	/* now check row numbers */
	printf("num_row %ld statuses[0] %d statuses[1] %d odbc3 %d\n", (long int) num_row,
		(int) statuses[0], (int) statuses[1], odbc_use_version3);

	if (odbc_use_version3 || !normal_fetch) {
		if (num_row != ROWS || statuses[0] != SQL_ROW_SUCCESS || statuses[1] != SQL_ROW_SUCCESS) {
			fprintf(stderr, "result error 1\n");
			exit(1);
		}
	} else {
		if (data[0].i != 1 || data[1].i != 0xdeadbeef) {
			fprintf(stderr, "result error 2\n");
			exit(1);
		}
	}

	FILL(statuses, 8765);
	num_row = -3;
	if (normal_fetch)
		CHKFetch("S");
	else
		CHKFetchScroll(SQL_FETCH_NEXT, 0, "S");
}
Esempio n. 3
0
int
main(int argc, char **argv)
{
	SQLRETURN RetCode;
	SQLHSTMT old_odbc_stmt = SQL_NULL_HSTMT;
	int i;

	int key;
	SQLLEN vind0;
	int cnt = 2, wide;
	char sql[256];
	test_info *t = NULL;

	odbc_use_version3 = 1;
	odbc_connect();

	/* tests (W)CHAR/BINARY -> (W)CHAR/BINARY (9 cases) */
	add_test(SQL_C_BINARY, SQL_LONGVARCHAR,   "TEXT",  123, 1 );
	add_test(SQL_C_BINARY, SQL_LONGVARBINARY, "IMAGE", 987, 25);
	add_test(SQL_C_CHAR,   SQL_LONGVARBINARY, "IMAGE", 987, 25);
	add_test(SQL_C_CHAR,   SQL_LONGVARCHAR,   "TEXT",  343, 47);
	add_test(SQL_C_WCHAR,  SQL_LONGVARBINARY, "IMAGE", 561, 29);
	add_test(SQL_C_WCHAR,  SQL_LONGVARCHAR,   "TEXT",  698, 24);
	if (odbc_db_is_microsoft()) {
		add_test(SQL_C_BINARY, SQL_WLONGVARCHAR, "NTEXT", 765, 12);
		add_test(SQL_C_CHAR,   SQL_WLONGVARCHAR, "NTEXT", 237, 71);
		add_test(SQL_C_WCHAR,  SQL_WLONGVARCHAR, "NTEXT", 687, 68);
	}

	strcpy(sql, "CREATE TABLE #tt(k INT");
	for (t = test_infos; t < test_infos+num_tests; ++t)
		sprintf(strchr(sql, 0), ",f%u %s", t->num, t->db_type);
	strcat(sql, ",v INT)");
	odbc_command(sql);

	old_odbc_stmt = odbc_stmt;
	odbc_stmt = SQL_NULL_HSTMT;

	/* Insert rows ... */

	for (i = 0; i < cnt; i++) {
		/* MS do not save correctly char -> binary */
		if (!odbc_driver_is_freetds() && i)
			continue;

		CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "S");

		strcpy(sql, "INSERT INTO #tt VALUES(?");
		for (t = test_infos; t < test_infos+num_tests; ++t)
			strcat(sql, ",?");
		strcat(sql, ",?)");
		CHKPrepare(T(sql), SQL_NTS, "S");

		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");
		for (t = test_infos; t < test_infos+num_tests; ++t)
			CHKBindParameter(t->num+1, SQL_PARAM_INPUT, t->c_type, t->sql_type, 0x10000000, 0, t->buf, 0, &t->vind, "S");

		CHKBindParameter(num_tests+2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");

		key = i;
		vind0 = 0;

		printf(">> insert... %d\n", i);
		RetCode = CHKExecute("SINe");
		while (RetCode == SQL_NEED_DATA) {
			char *p;

			RetCode = CHKParamData((SQLPOINTER) & p, "SINe");
			printf(">> SQLParamData: ptr = %p  RetCode = %d\n", (void *) p, RetCode);
			if (RetCode == SQL_NEED_DATA) {
				for (t = test_infos; t < test_infos+num_tests && t->buf != p; ++t)
					;
				assert(t < test_infos+num_tests);
				if (t->c_type == SQL_C_CHAR || t->c_type == SQL_C_WCHAR) {
					unsigned char_len = 1;

					fill_hex(p, NBYTES, t->gen1, t->gen2);
					if (t->c_type == SQL_C_WCHAR) {
						char_len = sizeof(SQLWCHAR);
						odbc_to_sqlwchar((SQLWCHAR*) p, p, NBYTES * 2);
					}

					CHKPutData(p, (NBYTES - (i&1)) * char_len, "S");

					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));

					CHKPutData(p + (NBYTES - (i&1)) * char_len, (NBYTES + (i&1)) * char_len, "S");

					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
				} else {
					CHKPutData(p, NBYTES, "S");

					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
				}
			}
		}

		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
		odbc_stmt = SQL_NULL_HSTMT;
	}

	/* Now fetch rows ... */

	for (wide = 0; wide < 2; ++wide)
	for (i = 0; i < cnt; i++) {
		/* MS do not save correctly char -> binary */
		if (!odbc_driver_is_freetds() && i)
			continue;


		CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "S");

		if (odbc_db_is_microsoft()) {
			CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S");
			CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
		}

		strcpy(sql, "SELECT ");
		for (t = test_infos; t < test_infos+num_tests; ++t)
			sprintf(strchr(sql, 0), "f%u,", t->num);
		strcat(sql, "v FROM #tt WHERE k = ?");
		CHKPrepare(T(sql), SQL_NTS, "S");

		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0, "S");

		for (t = test_infos; t < test_infos+num_tests; ++t) {
			t->vind = SQL_DATA_AT_EXEC;
			CHKBindCol(t->num, SQL_C_BINARY, NULL, 0, &t->vind, "S");
		}
		CHKBindCol(num_tests+1, SQL_C_LONG, &key, 0, &vind0, "S");

		vind0 = 0;

		CHKExecute("S");

		CHKFetchScroll(SQL_FETCH_NEXT, 0, "S");
		printf(">> fetch... %d\n", i);

		for (t = test_infos; t < test_infos+num_tests; ++t) {
			if (t->c_type == SQL_C_CHAR || t->c_type == SQL_C_WCHAR)
				readBlobAsChar(t, i, wide);
			else
				readBlob(t);
		}

		CHKCloseCursor("S");
		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
		odbc_stmt = SQL_NULL_HSTMT;
	}

	odbc_stmt = old_odbc_stmt;

	free_tests();
	odbc_disconnect();

	if (!failed)
		printf("ok!\n");

	return failed ? 1 : 0;
}
Esempio n. 4
0
int
main(int argc, char *argv[])
{
#define ROWS 3
#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;
	int i_test;

	typedef struct _test
	{
		SQLUSMALLINT type;
		SQLINTEGER irow;
		int start;
		int num;
	} TEST;

	static const TEST tests[] = {
		{SQL_FETCH_NEXT, 0, 1, 3},
		{SQL_FETCH_NEXT, 0, 4, 2},
		{SQL_FETCH_PRIOR, 0, 1, 3},
		{SQL_FETCH_NEXT, 0, 4, 2},
		{SQL_FETCH_NEXT, 0, -1, -1},
		{SQL_FETCH_FIRST, 0, 1, 3},
		{SQL_FETCH_ABSOLUTE, 3, 3, 3},
		{SQL_FETCH_RELATIVE, 1, 4, 2},
		{SQL_FETCH_LAST, 0, 3, 3}
	};
	const int num_tests = sizeof(tests) / sizeof(TEST);

	odbc_use_version3 = 1;

	odbc_connect();
	odbc_check_cursor();

	/* create test table */
	odbc_command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
	odbc_command("CREATE TABLE #test(i int, c varchar(6))");
	odbc_command("INSERT INTO #test(i, c) VALUES(1, 'a')");
	odbc_command("INSERT INTO #test(i, c) VALUES(2, 'bb')");
	odbc_command("INSERT INTO #test(i, c) VALUES(3, 'ccc')");
	odbc_command("INSERT INTO #test(i, c) VALUES(4, 'dddd')");
	odbc_command("INSERT INTO #test(i, c) VALUES(5, 'eeeee')");

	/* set cursor options */
	odbc_reset_statement();
	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 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");

	/* */
	CHKExecDirect(T("SELECT i, c FROM #test"), 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");

	for (i_test = 0; i_test < num_tests; ++i_test) {
		const TEST *t = &tests[i_test];

		printf("Test %d\n", i_test + 1);

		if (t->start == -1) {
			CHKFetchScroll(t->type, t->irow, "No");
		} else {
			CHKFetchScroll(t->type, t->irow, "S");

			if (t->start < 1) {
				fprintf(stderr, "Rows not expected\n");
				exit(1);
			}

			/* 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");

			if (num_row != t->num) {
				fprintf(stderr, "Expected %d rows, got %d\n", t->num, (int) num_row);
				exit(1);
			}

			for (i = 0; i < num_row; ++i) {
				char name[10];

				memset(name, 0, sizeof(name));
				memset(name, 'a' - 1 + i + t->start, i + t->start);
				if (n[i] != i + t->start || c_len[i] != strlen(name) || strcmp(c[i], name) != 0) {
					fprintf(stderr, "Wrong row returned\n");
					fprintf(stderr, "\tn %d %d\n", (int) n[i], i + t->start);
					fprintf(stderr, "\tc len %d %d\n", (int) c_len[i], (int) strlen(name));
					fprintf(stderr, "\tc %s %s\n", c[i], name);
					exit(1);
				}
			}
		}
	}

	odbc_reset_statement();

	odbc_disconnect();
	return 0;
}