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; }
int main(int argc, char **argv) { #define ARRAY_SIZE 10 SQLCHAR v_dec[ARRAY_SIZE][21]; SQLLEN v_ind[ARRAY_SIZE]; SQLULEN nrows; odbc_use_version3 = 1; odbc_connect(); odbc_check_cursor(); odbc_command("IF OBJECT_ID('mytab1') IS NOT NULL DROP TABLE mytab1"); odbc_command("CREATE TABLE mytab1 ( k INT, d DECIMAL(10,2))"); odbc_command("INSERT INTO mytab1 VALUES ( 201, 111.11 )"); /*SQLExecDirect(m_hstmt, (SQLCHAR *) "insert into mytab1 values ( 202, 222.22 )", SQL_NTS); */ odbc_command("INSERT INTO mytab1 VALUES ( 202, null )"); odbc_reset_statement(); CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER) SQL_BIND_BY_COLUMN, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ARRAY_SIZE, SQL_IS_UINTEGER, "S"); CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, (SQLPOINTER) & (nrows), SQL_IS_UINTEGER, "S"); CHKPrepare(T("SELECT SUM(d) FROM mytab1"), SQL_NTS, "S"); CHKExecute("I"); #if 0 CHKMoreResults("S"); /* skip warning*/ #endif CHKBindCol(1, SQL_C_CHAR, v_dec, 21, v_ind, "S"); CHKFetch("S"); printf("fetch 1: rows fetched = %d\n", (int) nrows); printf("fetch 1: value = [%s]\n", v_dec[0]); CHKFetch("No"); CHKMoreResults("No"); odbc_command("drop table mytab1"); odbc_disconnect(); return 0; }
static void CheckType(SQLSMALLINT type, SQLSMALLINT expected, const char *string_type, int line) { SQLSMALLINT out_type; SQLLEN ind; SQLRETURN RetCode; printf("CheckType %d\n", line); CHKBindCol(2, SQL_C_SSHORT, &out_type, 0, &ind, "SI"); CHKGetTypeInfo(type, "SI"); RetCode = CHKFetch("SNo"); switch (RetCode) { case SQL_SUCCESS: if (expected == SQL_UNKNOWN_TYPE) { fprintf(stderr, "Data not expected (type %d - %s) line %d\n", type, string_type, line); odbc_disconnect(); exit(1); } if (expected != out_type) { fprintf(stderr, "Got type %d expected %d. Input type %d - %s line %d\n", out_type, expected, type, string_type, line); odbc_disconnect(); exit(1); } break; case SQL_NO_DATA: if (expected != SQL_UNKNOWN_TYPE) { fprintf(stderr, "Data expected. Inpute type %d - %s line %d\n", type, string_type, line); odbc_disconnect(); exit(1); } break; } SQLFreeStmt(odbc_stmt, SQL_UNBIND); Flushodbc_stmt(); }
int main(int argc, char *argv[]) { int i; SQLLEN len; #ifdef HAVE_SQLROWSETSIZE SQLROWSETSIZE row_count; #else SQLULEN row_count; #endif SQLUSMALLINT statuses[10]; char buf[32]; odbc_use_version3 = 1; odbc_connect(); /* initial value should be 1 */ CHKGetStmtAttr(SQL_ROWSET_SIZE, &len, sizeof(len), NULL, "S"); if (len != 1) { fprintf(stderr, "len should be 1\n"); odbc_disconnect(); return 1; } /* check invalid parameter values */ test_err(-123); test_err(-1); test_err(0); odbc_check_cursor(); /* set some correct values */ CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0, "S"); CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0, "S"); /* now check that SQLExtendedFetch works as expected */ odbc_command("CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))"); for (i = 0; i < 10; ++i) { char s[10]; char sql[128]; memset(s, 'a' + i, 9); s[9] = 0; sprintf(sql, "INSERT INTO #rowset(n,c) VALUES(%d,'%s')", i+1, s); odbc_command(sql); } odbc_reset_statement(); CHKSetStmtOption(SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC, "S"); CHKExecDirect((SQLCHAR *) "SELECT * FROM #rowset ORDER BY n", SQL_NTS, "SI"); CHKBindCol(2, SQL_C_CHAR, buf, sizeof(buf), &len, "S"); row_count = 0xdeadbeef; memset(statuses, 0x55, sizeof(statuses)); CHKExtendedFetch(SQL_FETCH_NEXT, 1, &row_count, statuses, "S"); if (row_count != 1 || statuses[0] != SQL_ROW_SUCCESS || strcmp(buf, "aaaaaaaaa") != 0) { fprintf(stderr, "Invalid result\n"); odbc_disconnect(); return 1; } odbc_disconnect(); printf("Done.\n"); return 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"); } }
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; }
static void DoTest(int version3) { char name[128], params[128]; SQLSMALLINT type, is_unsigned; SQLINTEGER col_size, min_scale; SQLLEN ind1, ind2, ind3, ind4, ind5, ind6; int date_time_supported = 0; int name_version3; odbc_use_version3 = version3; name_version3 = version3; odbc_connect(); printf("Using ODBC version %d\n", version3 ? 3 : 2); /* test column name */ /* MS ODBC use always ODBC 3 names even in ODBC 2 mode */ if (!odbc_driver_is_freetds()) name_version3 = 1; CHKGetTypeInfo(SQL_ALL_TYPES, "SI"); TestName(1, "TYPE_NAME"); TestName(2, "DATA_TYPE"); TestName(3, name_version3 ? "COLUMN_SIZE" : "PRECISION"); TestName(4, "LITERAL_PREFIX"); TestName(5, "LITERAL_SUFFIX"); TestName(6, "CREATE_PARAMS"); TestName(7, "NULLABLE"); TestName(8, "CASE_SENSITIVE"); TestName(9, "SEARCHABLE"); TestName(10, "UNSIGNED_ATTRIBUTE"); TestName(11, name_version3 ? "FIXED_PREC_SCALE" : "MONEY"); TestName(12, name_version3 ? "AUTO_UNIQUE_VALUE" : "AUTO_INCREMENT"); TestName(13, "LOCAL_TYPE_NAME"); TestName(14, "MINIMUM_SCALE"); TestName(15, "MAXIMUM_SCALE"); /* TODO test these column for ODBC 3 */ /* ODBC 3.0 SQL_DATA_TYPE SQL_DATETIME_SUB NUM_PREC_RADIX INTERVAL_PRECISION */ Flushodbc_stmt(); /* TODO test if SQL_ALL_TYPES returns right numeric type for timestamp */ /* numeric type for data */ /* test for date/time support */ if (odbc_command_with_result(odbc_stmt, "select cast(getdate() as date)") == SQL_SUCCESS) date_time_supported = 1; SQLCloseCursor(odbc_stmt); #define CHECK_TYPE(in,out) CheckType(in, out, #in, __LINE__) /* under Sybase this type require extra handling, check it */ CHECK_TYPE(SQL_VARCHAR, SQL_VARCHAR); CHECK_TYPE(SQL_DATE, date_time_supported && !version3 ? SQL_DATE : SQL_UNKNOWN_TYPE); CHECK_TYPE(SQL_TIME, date_time_supported && !version3 ? SQL_TIME : SQL_UNKNOWN_TYPE); /* MS ODBC returns S1004 (HY004), TODO support it */ if (odbc_driver_is_freetds() || version3) { CHECK_TYPE(SQL_TYPE_DATE, date_time_supported && version3 ? SQL_TYPE_DATE : SQL_UNKNOWN_TYPE); CHECK_TYPE(SQL_TYPE_TIME, date_time_supported && version3 ? SQL_TYPE_TIME : SQL_UNKNOWN_TYPE); } /* TODO MS ODBC handle SQL_TIMESTAMP even for ODBC 3 */ if (odbc_driver_is_freetds()) CHECK_TYPE(SQL_TIMESTAMP, version3 ? SQL_UNKNOWN_TYPE : SQL_TIMESTAMP); else CHECK_TYPE(SQL_TIMESTAMP, version3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP); /* MS ODBC returns S1004 (HY004), TODO support it */ if (odbc_driver_is_freetds() || version3) { CHECK_TYPE(SQL_TYPE_TIMESTAMP, version3 ? SQL_TYPE_TIMESTAMP : SQL_UNKNOWN_TYPE); } /* TODO implement this part of test */ /* varchar/nvarchar before sysname */ /* test binding (not all column, required for Oracle) */ CHKGetTypeInfo(SQL_ALL_TYPES, "SI"); CHKBindCol(1, SQL_C_CHAR, name, sizeof(name), &ind1, "SI"); CHKBindCol(2, SQL_C_SSHORT, &type, 0, &ind2, "SI"); CHKBindCol(3, SQL_C_SLONG, &col_size, 0, &ind3, "SI"); CHKBindCol(6, SQL_C_CHAR, params, sizeof(params), &ind4, "SI"); CHKBindCol(10, SQL_C_SSHORT, &is_unsigned, 0, &ind5, "SI"); CHKBindCol(14, SQL_C_SSHORT, &min_scale, 0, &ind6, "SI"); while (CHKFetch("SNo") == SQL_SUCCESS) ; SQLFreeStmt(odbc_stmt, SQL_UNBIND); Flushodbc_stmt(); /* check WVARCHAR for no pending data */ if (odbc_db_is_microsoft() || strncmp(odbc_db_version(), "15.00.", 6) >= 0) { CHKGetTypeInfo(SQL_WVARCHAR, "SI"); CHKFetch("S"); if (odbc_db_is_microsoft()) CHKFetch("S"); CHKFetch("No"); CHKGetTypeInfo(SQL_BINARY, "SI"); } odbc_disconnect(); }
static void test_rows(void) { 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_ird_params1(int2ptr(0x01020304)); check_ird_params(); set_ird_params2(int2ptr(0xabcdef12)); check_ird_params(); /* now see results */ for (p = row_set; ; ++p) { const char *test_name = NULL; odbc_reset_statement(); len = 0xdeadbeef; len <<= 16; len <<= 16; len |= 12345678; if (*p) (*p)(&len); check_ird_params(); #if 0 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"); #endif CHKBindCol(1, SQL_C_ULONG, ids, 0, id_lens, "S"); if (*p) { CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S"); odbc_command("SELECT DISTINCT i FROM #tmp1"); SQLFetch(odbc_stmt); test_name = "SQLSetStmtAttr"; } else { CHKSetStmtAttr(SQL_ROWSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S"); odbc_command("SELECT DISTINCT i FROM #tmp1"); CHKExtendedFetch(SQL_FETCH_NEXT, 0, &len, NULL, "S"); test_name = "SQLExtendedFetch"; } SQLMoreResults(odbc_stmt); l = len; len >>= 16; h = len >> 16; l &= 0xfffffffflu; if (h != 0 || l != 2) { fprintf(stderr, "Wrong number returned in rows high %lu(0x%lx) low %lu(0x%lx) test %s\n", h, h, l, l, test_name); exit(1); } if (!*p) break; } free(ids); free(id_lens); }
int main(int argc, char *argv[]) { char tmp[512]; char out[32]; SQLLEN n_len; SQLSMALLINT len; const char * const*p; int n; if (odbc_read_login_info()) exit(1); /* connect string using DSN */ init_connect(); sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", odbc_server, odbc_user, odbc_password, odbc_database); CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI"); if (!odbc_driver_is_freetds()) { odbc_disconnect(); printf("Driver is not FreeTDS, exiting\n"); odbc_test_skipped(); return 0; } if (!odbc_db_is_microsoft() || odbc_db_version_int() < 0x08000000u || odbc_tds_version() < 0x701) { odbc_disconnect(); /* protocol till 7.1 does not support telling encoding so we * cannot understand how the string is encoded */ printf("Test for MSSQL only using protocol 7.1\n"); odbc_test_skipped(); return 0; } CHKAllocStmt(&odbc_stmt, "S"); /* create test table */ odbc_command("CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)"); /* insert with INSERT statements */ for (n = 0, p = strings_hex; p[n]; ++n) { sprintf(tmp, "INSERT INTO #tmpHebrew VALUES(%d, CAST(%s AS NVARCHAR(10)))", n+1, p[n]); odbc_command(tmp); } /* test conversions in libTDS */ odbc_command("SELECT v FROM #tmpHebrew"); /* insert with SQLPrepare/SQLBindParameter/SQLExecute */ CHKBindCol(1, SQL_C_CHAR, out, sizeof(out), &n_len, "S"); for (n = 0, p = strings; p[n]; ++n) { CHKFetch("S"); if (n_len != strlen(p[n]) || strcmp(p[n], out) != 0) { fprintf(stderr, "Wrong row %d %s\n", n, out); odbc_disconnect(); return 1; } } odbc_disconnect(); printf("Done.\n"); return 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"); }
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; }