static int dbd_freetds_get_row(apr_pool_t *pool, apr_dbd_results_t *res, apr_dbd_row_t **rowp, int rownum) { RETCODE rv = 0; apr_dbd_row_t *row = *rowp; int sequential = ((rownum >= 0) && res->random) ? 0 : 1; if (row == NULL) { row = apr_palloc(pool, sizeof(apr_dbd_row_t)); *rowp = row; row->res = res; } /* else { if ( sequential ) { ++row->n; } else { row->n = rownum; } } */ if (sequential) { rv = dbnextrow(res->proc); } else { rv = (rownum >= 0) ? dbgetrow(res->proc, rownum) : NO_MORE_ROWS; } switch (rv) { case SUCCEED: return 0; case REG_ROW: return 0; case NO_MORE_ROWS: apr_pool_cleanup_run(res->pool, res->proc, clear_result); *rowp = NULL; return -1; case FAIL: return 1; case BUF_FULL: return 2; /* FIXME */ default: return 3; } return 0; }
static ngx_int_t ngx_dbd_freetds_row_read(ngx_dbd_t *dbd) { ngx_dbd_freetds_ctx_t *ctx; ngx_log_debug0(NGX_LOG_DEBUG_MYSQL, dbd->log, 0, "dbd freetds row read"); ctx = dbd->ctx; #if 0 /* dbsetrow: set current row */ /* dbclrbuf */ r = dbfirstrow(dbd->proc); r = dblastrow(dbd->proc); r = dbcurrow(dbd->proc); dbd->err = dbgetrow(dbd->proc, row + 1); #endif ctx->err = dbnextrow(ctx->db); switch (ctx->err) { case SUCCEED: case REG_ROW: ctx->cur_col = 0; return NGX_OK; case NO_MORE_ROWS: return NGX_DONE; case FAIL: case BUF_FULL: /* TODO: case computeid: */ default: ngx_log_error(NGX_LOG_ALERT, dbd->log, 0, "dbnextrow() failed (err:%d)", ctx->err); return NGX_ERROR; } }
int main(int argc, char **argv) { LOGINREC *login; DBPROCESS *dbproc; int i; char teststr[1024]; DBINT testint; set_malloc_options(); read_login_info(argc, argv); printf("Starting %s\n", argv[0]); /* Fortify_EnterScope(); */ dbinit(); dberrhandle(syb_err_handler); dbmsghandle(syb_msg_handler); printf("About to logon\n"); login = dblogin(); DBSETLPWD(login, PASSWORD); DBSETLUSER(login, USER); DBSETLAPP(login, "text_buffer"); DBSETLHOST(login, "ntbox.dntis.ro"); printf("About to open\n"); dbproc = dbopen(login, SERVER); if (strlen(DATABASE)) dbuse(dbproc, DATABASE); dbloginfree(login); #ifdef MICROSOFT_DBLIB dbsetopt(dbproc, DBBUFFER, "100"); #else dbsetopt(dbproc, DBBUFFER, "100", 0); #endif printf("creating table\n"); sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } printf("insert\n"); sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } printf("select\n"); dbcmd(dbproc, "select * from #dblib order by i"); dbsqlexec(dbproc); if (dbresults(dbproc) != SUCCEED) { printf("Was expecting a result set."); return 1; } for (i = 1; i <= dbnumcols(dbproc); i++) { printf("col %d is %s\n", i, dbcolname(dbproc, i)); } dbbind(dbproc, 1, INTBIND, 0, (BYTE *) & testint); dbbind(dbproc, 2, STRINGBIND, 0, (BYTE *) teststr); if (REG_ROW != dbnextrow(dbproc)) { fprintf(stderr, "dblib failed for %s:%d\n", __FILE__, __LINE__); return 1; } if (dbdatlen(dbproc, 2) != 6 || 0 != strcmp("ABCDEF", teststr)) { fprintf(stderr, "Expected |%s|, found |%s|\n", "ABCDEF", teststr); fprintf(stderr, "dblib failed for %s:%d\n", __FILE__, __LINE__); return 1; } if (REG_ROW != dbnextrow(dbproc)) { fprintf(stderr, "dblib failed for %s:%d\n", __FILE__, __LINE__); return 1; } if (dbdatlen(dbproc, 2) != 3 || 0 != strcmp("abc", teststr)) { fprintf(stderr, "Expected |%s|, found |%s|\n", "abc", teststr); fprintf(stderr, "dblib failed for %s:%d\n", __FILE__, __LINE__); return 1; } /* get again row 1 */ dbgetrow(dbproc, 1); /* here length and string should be ok */ if (dbdatlen(dbproc, 2) != 6 || 0 != strcmp("ABCDEF", teststr)) { fprintf(stderr, "Expected |%s|, found |%s|\n", "ABCDEF", teststr); fprintf(stderr, "dblib failed for %s:%d\n", __FILE__, __LINE__); return 1; } dbgetrow(dbproc, 2); if (dbdatlen(dbproc, 2) != 3 || 0 != strcmp("abc", teststr)) { fprintf(stderr, "Expected |%s|, found |%s|\n", "abc", teststr); fprintf(stderr, "dblib failed for %s:%d\n", __FILE__, __LINE__); return 1; } dbexit(); printf("%s %s\n", __FILE__, (0 ? "failed!" : "OK")); return 0; }
int main(int argc, char **argv) { LOGINREC *login; DBPROCESS *dbproc; DBINT testint; STATUS rc; int i, iresults; char teststr[1024]; int rows_in_buffer, limit_rows; const int buffer_count = 10; const int rows_to_add = 50; set_malloc_options(); read_login_info(argc, argv); fprintf(stdout, "Starting %s\n", argv[0]); /* Fortify_EnterScope(); */ dbinit(); dberrhandle(syb_err_handler); dbmsghandle(syb_msg_handler); fprintf(stdout, "About to logon\n"); login = dblogin(); DBSETLPWD(login, PASSWORD); DBSETLUSER(login, USER); DBSETLAPP(login, "t0002"); fprintf(stdout, "About to open %s..%s\n", SERVER, DATABASE); dbproc = dbopen(login, SERVER); if (strlen(DATABASE)) dbuse(dbproc, DATABASE); dbloginfree(login); fprintf(stdout, "Setting row buffer to 10 rows\n"); #ifdef MICROSOFT_DBLIB dbsetopt(dbproc, DBBUFFER, "10"); #else dbsetopt(dbproc, DBBUFFER, "10", 0); #endif sql_cmd(dbproc); /* drop table if exists */ dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } if (dbresults(dbproc) != NO_MORE_RESULTS) { fprintf(stdout, "Failed: dbresults call after NO_MORE_RESULTS should return NO_MORE_RESULTS.\n"); failed = 1; } sql_cmd(dbproc); /* create table */ dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } for (i = 1; i <= rows_to_add; i++) { sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } } sql_cmd(dbproc); /* two result sets */ dbsqlexec(dbproc); for (iresults=1; iresults <= 2; iresults++ ) { fprintf(stdout, "fetching resultset %i\n", iresults); if (dbresults(dbproc) != SUCCEED) { fprintf(stderr, "Was expecting a result set %d.\n", iresults); if( iresults == 2 ) fprintf(stderr, "Buffering with multiple resultsets is broken.\n"); exit(1); } rows_in_buffer = 0; for (i = 1; i <= dbnumcols(dbproc); i++) printf("col %d is [%s]\n", i, dbcolname(dbproc, i)); dbbind(dbproc, 1, INTBIND, 0, (BYTE *) & testint); dbbind(dbproc, 2, STRINGBIND, 0, (BYTE *) teststr); /* Fetch a result set */ /* Second resultset stops at row 46 */ limit_rows = rows_to_add - (iresults == 2 ? 4 : 0); for (i=0; i < limit_rows;) { fprintf(stdout, "clearing %d rows from buffer\n", rows_in_buffer ? buffer_count - 1 : buffer_count); #ifdef MICROSOFT_DBLIB if (i == 0) { rc = dbnextrow(dbproc); assert(rc == REG_ROW); ++i; rows_in_buffer = 1; } #endif dbclrbuf(dbproc, buffer_count); rows_in_buffer = rows_in_buffer ? 1 : 0; do { int rc; i++; if (REG_ROW != (rc = dbnextrow(dbproc))) { failed = 1; fprintf(stderr, "Failed: Expected a row (%s:%d)\n", __FILE__, __LINE__); if (rc == BUF_FULL) fprintf(stderr, "Failed: dbnextrow returned BUF_FULL (%d). Fix dbclrbuf.\n", rc); exit(1); } ++rows_in_buffer; verify(i, testint, teststr); } while (rows_in_buffer < buffer_count && i < limit_rows); if (rows_in_buffer == buffer_count) { /* The buffer should be full */ assert(BUF_FULL == dbnextrow(dbproc)); } } if (iresults == 1) { fprintf(stdout, "clearing %d rows from buffer\n", buffer_count); dbclrbuf(dbproc, buffer_count); while (dbnextrow(dbproc) != NO_MORE_ROWS) { abort(); /* All rows were read: should not enter loop */ } } } printf("\n"); /* * Now test the buffered rows. * Should be operating on rows 37-46 of 2nd resultset */ rc = dbgetrow(dbproc, 1); if(rc != NO_MORE_ROWS) /* row 1 is not among the 31-40 in the buffer */ fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc); assert(rc == NO_MORE_ROWS); rc = dbgetrow(dbproc, 37); if(rc != REG_ROW) fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc); assert(rc == REG_ROW); verify(37, testint, teststr); /* first buffered row should be 37 */ rc = dbnextrow(dbproc); if(rc != REG_ROW) fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc); assert(rc == REG_ROW); verify(38, testint, teststr); /* next buffered row should be 38 */ rc = dbgetrow(dbproc, 11); assert(rc == NO_MORE_ROWS); /* only 10 (not 11) rows buffered */ rc = dbgetrow(dbproc, 46); assert(rc == REG_ROW); verify(46, testint, teststr); /* last buffered row should be 46 */ /* Attempt dbnextrow when buffer has no space (10 out of 10 in use). */ rc = dbnextrow(dbproc); assert(rc == BUF_FULL); dbclrbuf(dbproc, 3); /* remove rows 37, 38, and 39 */ rc = dbnextrow(dbproc); assert(rc == REG_ROW); verify(47, testint, teststr); /* fetch row from database, should be 47 */ rc = dbnextrow(dbproc); assert(rc == REG_ROW); verify(48, testint, teststr); /* fetch row from database, should be 48 */ /* buffer contains 8 rows (40-47) try removing 10 rows */ dbclrbuf(dbproc, buffer_count); while (dbnextrow(dbproc) != NO_MORE_ROWS) { /* waste rows 49-50 */ } dbclose(dbproc); /* close while buffer not cleared: OK */ dbexit(); fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK")); return failed ? 1 : 0; }
int main(int argc, char **argv) { LOGINREC *login; DBPROCESS *dbproc; DBINT testint; STATUS rc; int i, iresults; char teststr[1024]; const int buffer_count = 10; const int rows_to_add = 50; const char tablename[] = "#dblib0002"; const char drop_if_exists[] = "if exists ( select 1 " "from tempdb..sysobjects " "where id = object_id('tempdb..%s') )\n" "\tdrop table %s\n"; set_malloc_options(); read_login_info(argc, argv); fprintf(stdout, "Start\n"); add_bread_crumb(); /* Fortify_EnterScope(); */ dbinit(); add_bread_crumb(); dberrhandle(syb_err_handler); dbmsghandle(syb_msg_handler); fprintf(stdout, "About to logon\n"); add_bread_crumb(); login = dblogin(); DBSETLPWD(login, PASSWORD); DBSETLUSER(login, USER); DBSETLAPP(login, "t0002"); fprintf(stdout, "About to open %s..%s\n", SERVER, DATABASE); add_bread_crumb(); dbproc = dbopen(login, SERVER); if (strlen(DATABASE)) dbuse(dbproc, DATABASE); add_bread_crumb(); dbloginfree(login); add_bread_crumb(); fprintf(stdout, "Setting row buffer to 10 rows\n"); #ifdef MICROSOFT_DBLIB dbsetopt(dbproc, DBBUFFER, "10"); #else dbsetopt(dbproc, DBBUFFER, "10", 0); #endif add_bread_crumb(); add_bread_crumb(); fprintf(stdout, drop_if_exists, tablename, tablename); dbfcmd(dbproc, drop_if_exists, tablename, tablename); add_bread_crumb(); dbsqlexec(dbproc); add_bread_crumb(); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } if (dbresults(dbproc) != NO_MORE_RESULTS) { fprintf(stdout, "Failed: dbresults call after NO_MORE_RESULTS should return NO_MORE_RESULTS.\n"); failed = 1; } add_bread_crumb(); fprintf(stdout, "create table %s (i int not null, s char(10) not null)\n", tablename); dbfcmd(dbproc, "create table %s (i int not null, s char(10) not null)", tablename); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } fprintf(stdout, "insert into %s [%d rows]\n", tablename, rows_to_add); for (i = 1; i <= rows_to_add; i++) { char cmd[1024]; sprintf(cmd, "insert into %s values (%d, 'row %03d')", tablename, i, i); dbcmd(dbproc, cmd); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } } fprintf(stdout, "select * from %s order by i\n", tablename); dbfcmd(dbproc, "select * from %s order by i\n", tablename); dbfcmd(dbproc, "select * from %s order by i\n", tablename); /* two result sets */ dbsqlexec(dbproc); add_bread_crumb(); for (iresults=1; iresults <= 2; iresults++ ) { fprintf(stdout, "fetching resultset %i\n", iresults); if (dbresults(dbproc) != SUCCEED) { add_bread_crumb(); fprintf(stderr, "Was expecting a result set %d.\n", iresults); if( iresults == 2 ) fprintf(stderr, "Buffering with multiple resultsets is broken.\n"); exit(1); } add_bread_crumb(); for (i = 1; i <= dbnumcols(dbproc); i++) { add_bread_crumb(); printf("col %d is [%s]\n", i, dbcolname(dbproc, i)); add_bread_crumb(); } add_bread_crumb(); dbbind(dbproc, 1, INTBIND, 0, (BYTE *) & testint); add_bread_crumb(); dbbind(dbproc, 2, STRINGBIND, 0, (BYTE *) teststr); add_bread_crumb(); /* Fetch a result set */ /* Second resultset stops at row 40 */ for (i=0; i < rows_to_add - (iresults == 2 ? buffer_count : 0);) { fprintf(stdout, "clearing %d rows from buffer\n", buffer_count); dbclrbuf(dbproc, buffer_count); do { int rc; i++; add_bread_crumb(); if (REG_ROW != (rc = dbnextrow(dbproc))) { failed = 1; fprintf(stderr, "Failed: Expected a row (%s:%d)\n", __FILE__, __LINE__); if (rc == BUF_FULL) fprintf(stderr, "Failed: dbnextrow returned BUF_FULL (%d). Fix dbclrbuf.\n", rc); exit(1); } add_bread_crumb(); verify(i, testint, teststr); } while (i % buffer_count); if (iresults == 1 && i == rows_to_add) { /* The buffer should be full */ assert(BUF_FULL == dbnextrow(dbproc)); } } if (iresults == 1) { fprintf(stdout, "clearing %d rows from buffer\n", buffer_count); dbclrbuf(dbproc, buffer_count); while (dbnextrow(dbproc) != NO_MORE_ROWS) { abort(); /* All rows were read: should not enter loop */ } } } /* * Now test the buffered rows. * Should be operating on rows 31-40 of 2nd resultset */ rc = dbgetrow(dbproc, 1); add_bread_crumb(); if(rc != NO_MORE_ROWS) /* row 1 is not among the 31-40 in the buffer */ fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc); assert(rc == NO_MORE_ROWS); rc = dbgetrow(dbproc, 31); add_bread_crumb(); if(rc != REG_ROW) fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc); assert(rc == REG_ROW); verify(31, testint, teststr); /* first buffered row should be 31 */ rc = dbnextrow(dbproc); add_bread_crumb(); if(rc != REG_ROW) fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc); assert(rc == REG_ROW); verify(32, testint, teststr); /* next buffered row should be 32 */ rc = dbgetrow(dbproc, 11); add_bread_crumb(); assert(rc == NO_MORE_ROWS); /* only 10 (not 11) rows buffered */ rc = dbgetrow(dbproc, 40); add_bread_crumb(); assert(rc == REG_ROW); verify(40, testint, teststr); /* last buffered row should be 40 */ /* Attempt dbnextrow when buffer has no space (10 out of 10 in use). */ rc = dbnextrow(dbproc); assert(rc == BUF_FULL); dbclrbuf(dbproc, 3); /* remove rows 31, 32, and 33 */ rc = dbnextrow(dbproc); add_bread_crumb(); assert(rc == REG_ROW); verify(41, testint, teststr); /* fetch row from database, should be 41 */ rc = dbnextrow(dbproc); add_bread_crumb(); assert(rc == REG_ROW); verify(42, testint, teststr); /* fetch row from database, should be 42 */ /* buffer contains 9 rows (34-42) try removing 10 rows */ dbclrbuf(dbproc, buffer_count); while (dbnextrow(dbproc) != NO_MORE_ROWS) { /* waste rows 43-50 */ } dbclose(dbproc); /* close while buffer not cleared: OK */ add_bread_crumb(); dbexit(); add_bread_crumb(); fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__); free_bread_crumb(); return failed ? 1 : 0; }