int main(int argc, char **argv) { LOGINREC *login; read_login_info(argc, argv); fprintf(stdout, "Starting %s\n", argv[0]); 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, "thread"); fprintf(stdout, "About to open \"%s\"\n", SERVER); dbproc = dbopen(login, SERVER); if (!dbproc) { fprintf(stderr, "Unable to connect to %s\n", SERVER); return 1; } dbloginfree(login); if (strlen(DATABASE)) dbuse(dbproc, DATABASE); test("VARCHAR(10)", 1); test("CHAR(10)", 1); test("TEXT", 1); test("NVARCHAR(10)", 0); #ifndef DBNTWIN32 if (dbtds(dbproc) >= DBTDS_7_0) test("NTEXT", 0); #endif test("VARCHAR(MAX)", 0); #ifndef DBNTWIN32 if (dbtds(dbproc) >= DBTDS_7_0) test("NVARCHAR(MAX)", 0); #endif dbexit(); return failed ? 1 : 0; }
static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value) { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; switch (attr) { case PDO_ATTR_DEFAULT_STR_PARAM: ZVAL_LONG(return_value, H->assume_national_character_set_strings ? PDO_PARAM_STR_NATL : PDO_PARAM_STR_CHAR); break; case PDO_ATTR_EMULATE_PREPARES: /* this is the only option available, but expose it so common tests and whatever else can introspect */ ZVAL_TRUE(return_value); break; case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER: ZVAL_BOOL(return_value, H->stringify_uniqueidentifier); break; case PDO_DBLIB_ATTR_VERSION: ZVAL_STRING(return_value, dbversion()); break; case PDO_DBLIB_ATTR_TDS_VERSION: dblib_get_tds_version(return_value, dbtds(H->link)); break; case PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS: ZVAL_BOOL(return_value, H->skip_empty_rowsets); break; case PDO_DBLIB_ATTR_DATETIME_CONVERT: ZVAL_BOOL(return_value, H->datetime_convert); break; default: return 0; } return 1; }
static VALUE rb_tinytds_connect(VALUE self, VALUE opts) { /* Parsing options hash to local vars. */ VALUE user, pass, dataserver, database, app, version, ltimeout, timeout, charset, azure; GET_CLIENT_WRAPPER(self); user = rb_hash_aref(opts, sym_username); pass = rb_hash_aref(opts, sym_password); dataserver = rb_hash_aref(opts, sym_dataserver); database = rb_hash_aref(opts, sym_database); app = rb_hash_aref(opts, sym_appname); version = rb_hash_aref(opts, sym_tds_version); ltimeout = rb_hash_aref(opts, sym_login_timeout); timeout = rb_hash_aref(opts, sym_timeout); charset = rb_hash_aref(opts, sym_encoding); azure = rb_hash_aref(opts, sym_azure); /* Dealing with options. */ if (dbinit() == FAIL) { rb_raise(cTinyTdsError, "failed dbinit() function"); return self; } dberrhandle(tinytds_err_handler); dbmsghandle(tinytds_msg_handler); cwrap->login = dblogin(); if (!NIL_P(version)) dbsetlversion(cwrap->login, NUM2INT(version)); if (!NIL_P(user)) dbsetluser(cwrap->login, StringValueCStr(user)); if (!NIL_P(pass)) dbsetlpwd(cwrap->login, StringValueCStr(pass)); if (!NIL_P(app)) dbsetlapp(cwrap->login, StringValueCStr(app)); if (!NIL_P(ltimeout)) dbsetlogintime(NUM2INT(ltimeout)); if (!NIL_P(timeout)) dbsettime(NUM2INT(timeout)); if (!NIL_P(charset)) DBSETLCHARSET(cwrap->login, StringValueCStr(charset)); if (!NIL_P(database) && (azure == Qtrue)) { #ifdef DBSETLDBNAME DBSETLDBNAME(cwrap->login, StringValueCStr(database)); #else rb_warn("TinyTds: Azure connections not supported in this version of FreeTDS.\n"); #endif } cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver)); if (cwrap->client) { VALUE transposed_encoding; cwrap->closed = 0; cwrap->charset = charset; if (!NIL_P(version)) dbsetversion(NUM2INT(version)); dbsetuserdata(cwrap->client, (BYTE*)cwrap->userdata); cwrap->userdata->closed = 0; if (!NIL_P(database) && (azure != Qtrue)) { dbuse(cwrap->client, StringValueCStr(database)); } transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset); cwrap->encoding = rb_enc_find(StringValueCStr(transposed_encoding)); if (dbtds(cwrap->client) <= 7) { cwrap->identity_insert_sql = "SELECT CAST(@@IDENTITY AS bigint) AS Ident"; } else { cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"; } } return self; }
static VALUE rb_tinytds_tds_version(VALUE self) { GET_CLIENT_WRAPPER(self); return INT2FIX(dbtds(cwrap->client)); }
static int test(int argc, char **argv, int over4k) { const int rows_to_add = 3; LOGINREC *login; DBPROCESS *dbproc; DBPROCESS *blobproc; int i; DBINT testint; FILE *fp; long result, isiz; char *blob, *rblob; unsigned char *textPtr, *timeStamp; char objname[256]; char sqlCmd[256]; char rbuf[BLOB_BLOCK_SIZE]; long numread; int numtowrite, numwritten; set_malloc_options(); read_login_info(argc, argv); fprintf(stdout, "Starting %s\n", argv[0]); 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, "t0014"); fprintf(stdout, "About to open %s..%s for user '%s'\n", SERVER, DATABASE, USER); dbproc = dbopen(login, SERVER); blobproc = dbopen(login, SERVER); if (strlen(DATABASE)) { dbuse(dbproc, DATABASE); dbuse(blobproc, DATABASE); } dbloginfree(login); fprintf(stdout, "After logon\n"); fprintf(stdout, "About to read binary input file\n"); if (argc == 1) { argv = testargs; argc = 3; } if (argc < 3) { fprintf(stderr, "Usage: %s infile outfile\n", argv[0]); return 1; } if ((fp = fopen(argv[1], "rb")) == NULL) { fprintf(stderr, "Cannot open input file: %s\n", argv[1]); return 2; } result = fseek(fp, 0, SEEK_END); isiz = ftell(fp); result = fseek(fp, 0, SEEK_SET); blob = (char *) malloc(isiz); result = fread((void *) blob, isiz, 1, fp); assert(result == 1); fclose(fp); /* FIXME this test seem to not work using temporary tables (sybase?)... */ fprintf(stdout, "Dropping table\n"); sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } fprintf(stdout, "creating table\n"); sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } fprintf(stdout, "insert\n"); for (i = 0; i < rows_to_add; i++) { sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } } for (i = 0; i < rows_to_add; i++) { sql_cmd(dbproc); dbsqlexec(dbproc); if (dbresults(dbproc) != SUCCEED) { fprintf(stderr, "Error inserting blob\n"); return 4; } while ((result = dbnextrow(dbproc)) != NO_MORE_ROWS) { result = REG_ROW; result = DBTXPLEN; strcpy(objname, "dblib0014.PigTure"); textPtr = dbtxptr(dbproc, 1); timeStamp = dbtxtimestamp(dbproc, 1); if (!textPtr && !timeStamp && dbtds(dbproc) >= DBTDS_7_2) { printf("Protocol 7.2+ detected, test not supported\n"); free(blob); dbexit(); exit(0); } /* * Use #ifdef if you want to test dbmoretext mode (needed for 16-bit apps) * Use #ifndef for big buffer version (32-bit) */ if (over4k) { if (dbwritetext(blobproc, objname, textPtr, DBTXPLEN, timeStamp, TRUE, isiz, (BYTE*) blob) != SUCCEED) return 5; } else { if (dbwritetext(blobproc, objname, textPtr, DBTXPLEN, timeStamp, TRUE, isiz, NULL) != SUCCEED) return 15; dbsqlok(blobproc); dbresults(blobproc); numtowrite = 0; /* Send the update value in chunks. */ for (numwritten = 0; numwritten < isiz; numwritten += numtowrite) { numtowrite = (isiz - numwritten); if (numtowrite > BLOB_BLOCK_SIZE) numtowrite = BLOB_BLOCK_SIZE; dbmoretext(blobproc, (DBINT) numtowrite, (BYTE *) (blob + numwritten)); } dbsqlok(blobproc); while (dbresults(blobproc) != NO_MORE_RESULTS); } } } fprintf(stdout, "select\n"); sql_cmd(dbproc); dbsqlexec(dbproc); if (dbresults(dbproc) != SUCCEED) { fprintf(stdout, "Was expecting a result set."); exit(1); } for (i = 1; i <= dbnumcols(dbproc); i++) { printf("col %d is %s\n", i, dbcolname(dbproc, i)); } if (SUCCEED != dbbind(dbproc, 1, INTBIND, -1, (BYTE *) & testint)) { fprintf(stderr, "Had problem with bind\n"); abort(); } for (i = 0; i < rows_to_add; i++) { char expected[1024]; sprintf(expected, "row %03d", i); if (REG_ROW != dbnextrow(dbproc)) { fprintf(stderr, "Failed. Expected a row\n"); exit(1); } if (testint != i) { fprintf(stderr, "Failed. Expected i to be %d, was %d\n", i, (int) testint); abort(); } /* get the image */ strcpy(sqlCmd, "SET TEXTSIZE 2147483647"); dbcmd(blobproc, sqlCmd); dbsqlexec(blobproc); if (dbresults(blobproc) != SUCCEED) { dbcancel(blobproc); return 16; } sprintf(sqlCmd, "SELECT PigTure FROM dblib0014 WHERE i = %d", i); dbcmd(blobproc, sqlCmd); dbsqlexec(blobproc); if (dbresults(blobproc) != SUCCEED) { fprintf(stderr, "Error extracting blob\n"); return 6; } numread = 0; rblob = NULL; while ((result = dbreadtext(blobproc, rbuf, BLOB_BLOCK_SIZE)) != NO_MORE_ROWS) { if (result != 0) { /* this indicates not end of row */ rblob = (char*) realloc(rblob, result + numread); memcpy((void *) (rblob + numread), (void *) rbuf, result); numread += result; } } if (i == 0) { printf("Saving first blob data row to file: %s\n", argv[2]); if ((fp = fopen(argv[2], "wb")) == NULL) { fprintf(stderr, "Unable to open output file: %s\n", argv[2]); return 3; } result = fwrite((void *) rblob, numread, 1, fp); fclose(fp); } printf("Read blob data row %d --> %s %ld byte comparison\n", (int) testint, (memcmp(blob, rblob, numread)) ? "failed" : "PASSED", numread); free(rblob); } if (dbnextrow(dbproc) != NO_MORE_ROWS) { fprintf(stderr, "Was expecting no more rows\n"); exit(1); } free(blob); fprintf(stdout, "Dropping table\n"); sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } dbexit(); return 0; }
static VALUE rb_tinytds_result_fetch_row(VALUE self, ID timezone, int symbolize_keys, int as_array) { VALUE row; /* Storing Values */ unsigned int i; /* Wrapper And Local Vars */ GET_RESULT_WRAPPER(self); /* Create Empty Row */ row = as_array ? rb_ary_new2(rwrap->number_of_fields) : rb_hash_new(); for (i = 0; i < rwrap->number_of_fields; i++) { VALUE val = Qnil; int col = i+1; int coltype = dbcoltype(rwrap->client, col); BYTE *data = dbdata(rwrap->client, col); DBINT data_len = dbdatlen(rwrap->client, col); int null_val = ((data == NULL) && (data_len == 0)); if (!null_val) { switch(coltype) { case SYBINT1: val = INT2FIX(*(DBTINYINT *)data); break; case SYBINT2: val = INT2FIX(*(DBSMALLINT *)data); break; case SYBINT4: val = INT2NUM(*(DBINT *)data); break; case SYBINT8: val = LL2NUM(*(DBBIGINT *)data); break; case SYBBIT: val = *(int *)data ? Qtrue : Qfalse; break; case SYBNUMERIC: case SYBDECIMAL: { DBTYPEINFO *data_info = dbcoltypeinfo(rwrap->client, col); int data_slength = (int)data_info->precision + (int)data_info->scale + 1; char converted_decimal[data_slength]; dbconvert(rwrap->client, coltype, data, data_len, SYBVARCHAR, (BYTE *)converted_decimal, -1); val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new2((char *)converted_decimal)); break; } case SYBFLT8: { double col_to_double = *(double *)data; val = (col_to_double == 0.000000) ? opt_float_zero : rb_float_new(col_to_double); break; } case SYBREAL: { float col_to_float = *(float *)data; val = (col_to_float == 0.0) ? opt_float_zero : rb_float_new(col_to_float); break; } case SYBMONEY: { DBMONEY *money = (DBMONEY *)data; char converted_money[25]; long long money_value = ((long long)money->mnyhigh << 32) | money->mnylow; sprintf(converted_money, "%" LONG_LONG_FORMAT, money_value); val = rb_funcall(cBigDecimal, intern_new, 2, rb_str_new2(converted_money), opt_four); val = rb_funcall(val, intern_divide, 1, opt_tenk); break; } case SYBMONEY4: { DBMONEY4 *money = (DBMONEY4 *)data; char converted_money[20]; sprintf(converted_money, "%f", money->mny4 / 10000.0); val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new2(converted_money)); break; } case SYBBINARY: case SYBIMAGE: val = rb_str_new((char *)data, (long)data_len); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(val, binaryEncoding); #endif break; case 36: { // SYBUNIQUE char converted_unique[37]; dbconvert(rwrap->client, coltype, data, 37, SYBVARCHAR, (BYTE *)converted_unique, -1); val = ENCODED_STR_NEW2(converted_unique); break; } case SYBDATETIME4: { DBDATETIME new_data; dbconvert(rwrap->client, coltype, data, data_len, SYBDATETIME, (BYTE *)&new_data, sizeof(new_data)); data = (BYTE *)&new_data; data_len = sizeof(new_data); } case SYBDATETIME: { DBDATEREC dr; dbdatecrack(rwrap->client, &dr, (DBDATETIME *)data); if (dr.year + dr.month + dr.day + dr.hour + dr.minute + dr.second + dr.millisecond != 0) { val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(dr.year), INT2NUM(dr.month), INT2NUM(dr.day), INT2NUM(dr.hour), INT2NUM(dr.minute), INT2NUM(dr.second), INT2NUM(dr.millisecond*1000)); } break; } case 40: // SYBMSDATE case 41: // SYBMSTIME case 42: // SYBMSDATETIME2 case 43: { // SYBMSDATETIMEOFFSET #ifdef DBVERSION_73 if (dbtds(rwrap->client) >= DBTDS_7_3) { DBDATEREC2 dr2; dbanydatecrack(rwrap->client, &dr2, coltype, data); switch(coltype) { case 40: { // SYBMSDATE val = rb_funcall(cDate, intern_new, 3, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day)); break; } case 41: { // SYBMSTIME VALUE rational_nsec = rb_Rational(INT2NUM(dr2.nanosecond), opt_onek); val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(1900), INT2NUM(1), INT2NUM(1), INT2NUM(dr2.hour), INT2NUM(dr2.minute), INT2NUM(dr2.second), rational_nsec); break; } case 42: { // SYBMSDATETIME2 VALUE rational_nsec = rb_Rational(INT2NUM(dr2.nanosecond), opt_onek); val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day), INT2NUM(dr2.hour), INT2NUM(dr2.minute), INT2NUM(dr2.second), rational_nsec); break; } case 43: { // SYBMSDATETIMEOFFSET long long numerator = ((long)dr2.second * (long long)1000000000) + (long long)dr2.nanosecond; VALUE rational_sec = rb_Rational(LL2NUM(numerator), opt_onebil); val = rb_funcall(rb_cTime, intern_new, 7, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day), INT2NUM(dr2.hour), INT2NUM(dr2.minute), rational_sec, INT2NUM(dr2.tzone*60)); break; } } } else { val = ENCODED_STR_NEW(data, data_len); } #else val = ENCODED_STR_NEW(data, data_len); #endif break; } case SYBCHAR: case SYBTEXT: val = ENCODED_STR_NEW(data, data_len); break; default: val = ENCODED_STR_NEW(data, data_len); break; } } if (as_array) { rb_ary_store(row, i, val); } else { VALUE key; if (rwrap->number_of_results == 0) { key = rb_ary_entry(rwrap->fields, i); } else { key = rb_ary_entry(rb_ary_entry(rwrap->fields, rwrap->number_of_results), i); } rb_hash_aset(row, key, val); } } return row; }
static VALUE rb_tinytds_connect(VALUE self, VALUE opts) { /* Parsing options hash to local vars. */ VALUE user, pass, dataserver, database, app, version, ltimeout, timeout, charset, azure, contained, use_utf16; GET_CLIENT_WRAPPER(self); user = rb_hash_aref(opts, sym_username); pass = rb_hash_aref(opts, sym_password); dataserver = rb_hash_aref(opts, sym_dataserver); database = rb_hash_aref(opts, sym_database); app = rb_hash_aref(opts, sym_appname); version = rb_hash_aref(opts, sym_tds_version); ltimeout = rb_hash_aref(opts, sym_login_timeout); timeout = rb_hash_aref(opts, sym_timeout); charset = rb_hash_aref(opts, sym_encoding); azure = rb_hash_aref(opts, sym_azure); contained = rb_hash_aref(opts, sym_contained); use_utf16 = rb_hash_aref(opts, sym_use_utf16); cwrap->userdata->message_handler = rb_hash_aref(opts, sym_message_handler); /* Dealing with options. */ if (dbinit() == FAIL) { rb_raise(cTinyTdsError, "failed dbinit() function"); return self; } dberrhandle(tinytds_err_handler); dbmsghandle(tinytds_msg_handler); cwrap->login = dblogin(); if (!NIL_P(version)) dbsetlversion(cwrap->login, NUM2INT(version)); if (!NIL_P(user)) dbsetluser(cwrap->login, StringValueCStr(user)); if (!NIL_P(pass)) dbsetlpwd(cwrap->login, StringValueCStr(pass)); if (!NIL_P(app)) dbsetlapp(cwrap->login, StringValueCStr(app)); if (!NIL_P(ltimeout)) dbsetlogintime(NUM2INT(ltimeout)); if (!NIL_P(charset)) DBSETLCHARSET(cwrap->login, StringValueCStr(charset)); if (!NIL_P(database)) { if (azure == Qtrue || contained == Qtrue) { #ifdef DBSETLDBNAME DBSETLDBNAME(cwrap->login, StringValueCStr(database)); #else if (azure == Qtrue) { rb_warn("TinyTds: :azure option is not supported in this version of FreeTDS.\n"); } if (contained == Qtrue) { rb_warn("TinyTds: :contained option is not supported in this version of FreeTDS.\n"); } #endif } } #ifdef DBSETUTF16 if (use_utf16 == Qtrue) { DBSETLUTF16(cwrap->login, 1); } if (use_utf16 == Qfalse) { DBSETLUTF16(cwrap->login, 0); } #else if (use_utf16 == Qtrue || use_utf16 == Qfalse) { rb_warning("TinyTds: Please consider upgrading to FreeTDS 0.99 or higher for better unicode support.\n"); } #endif cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver)); if (cwrap->client) { VALUE transposed_encoding, timeout_string; cwrap->closed = 0; cwrap->charset = charset; if (!NIL_P(version)) dbsetversion(NUM2INT(version)); if (!NIL_P(timeout)) { timeout_string = rb_sprintf("%"PRIsVALUE"", timeout); if (dbsetopt(cwrap->client, DBSETTIME, StringValueCStr(timeout_string), 0) == FAIL) { dbsettime(NUM2INT(timeout)); } } dbsetuserdata(cwrap->client, (BYTE*)cwrap->userdata); cwrap->userdata->closed = 0; if (!NIL_P(database) && (azure != Qtrue)) { dbuse(cwrap->client, StringValueCStr(database)); } transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset); cwrap->encoding = rb_enc_find(StringValueCStr(transposed_encoding)); if (dbtds(cwrap->client) <= 7) { cwrap->identity_insert_sql = "SELECT CAST(@@IDENTITY AS bigint) AS Ident"; } else { cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"; } } return self; }
static int test(int argc, char **argv, int over4k) { LOGINREC *login; int i; DBINT testint; FILE *fp; long result, isiz; char *blob, *rblob; DBBINARY *textPtr = NULL, *timeStamp = NULL; char objname[256]; char rbuf[BLOB_BLOCK_SIZE]; long numread; int data_ok; int numtowrite, numwritten; set_malloc_options(); read_login_info(argc, argv); fprintf(stdout, "Starting %s\n", argv[0]); 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, "t0013"); fprintf(stdout, "About to open, PASSWORD: %s, USER: %s, SERVER: %s\n", "", "", ""); /* PASSWORD, USER, SERVER); */ dbproc = dbopen(login, SERVER); dbprocw = dbopen(login, SERVER); if (strlen(DATABASE)) { dbuse(dbproc, DATABASE); dbuse(dbprocw, DATABASE); } dbloginfree(login); fprintf(stdout, "logged in\n"); if (argc == 1) { argv = testargs; argc = 3; } if (argc < 3) { fprintf(stderr, "Usage: %s infile outfile\n", argv[0]); return 1; } if ((fp = fopen(argv[1], "rb")) == NULL) { fprintf(stderr, "Cannot open input file: %s\n", argv[1]); return 2; } fprintf(stdout, "Reading binary input file\n"); fseek(fp, 0, SEEK_END); isiz = ftell(fp); fseek(fp, 0, SEEK_SET); blob = malloc(isiz); assert(blob); result = fread((void *) blob, isiz, 1, fp); assert(result == 1); fclose(fp); drop_table(); sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } sql_cmd(dbproc); dbsqlexec(dbproc); while (dbresults(dbproc) != NO_MORE_RESULTS) { /* nop */ } sql_cmd(dbproc); dbsqlexec(dbproc); if (dbresults(dbproc) != SUCCEED) { fprintf(stderr, "Error inserting blob\n"); return 4; } for (i=0; (result = dbnextrow(dbproc)) != NO_MORE_ROWS; i++) { assert(REG_ROW == result); printf("fetching row %d\n", i+1); strcpy(objname, TABLE_NAME ".PigTure"); textPtr = dbtxptr(dbproc, 1); timeStamp = dbtxtimestamp(dbproc, 1); break; /* can't proceed until no more rows */ } assert(REG_ROW == result || 0 < i); if (!textPtr && !timeStamp && dbtds(dbproc) >= DBTDS_7_2) { printf("Protocol 7.2+ detected, test not supported\n"); free(blob); dbclose(dbproc); dbproc = NULL; dbexit(); exit(0); } if (!textPtr) { fprintf(stderr, "Error getting textPtr\n"); exit(1); } /* * Use #ifdef if you want to test dbmoretext mode (needed for 16-bit apps) * Use #ifndef for big buffer version (32-bit) */ fprintf(stdout, "writing text ... "); if (over4k) { if (dbwritetext(dbprocw, objname, textPtr, DBTXPLEN, timeStamp, FALSE, isiz, (BYTE*) blob) != SUCCEED) return 5; fprintf(stdout, "done (in one shot)\n"); for (; (result = dbnextrow(dbproc)) != NO_MORE_ROWS; i++) { assert(REG_ROW == result); printf("fetching row %d?\n", i+1); } } else { if (dbwritetext(dbprocw, objname, textPtr, DBTXPLEN, timeStamp, FALSE, isiz, NULL) != SUCCEED) return 15; fprintf(stdout, "done\n"); fprintf(stdout, "dbsqlok\n"); dbsqlok(dbprocw); fprintf(stdout, "dbresults\n"); dbresults(dbprocw); numtowrite = 0; /* Send the update value in chunks. */ for (numwritten = 0; numwritten < isiz; numwritten += numtowrite) { fprintf(stdout, "dbmoretext %d\n", 1 + numwritten); numtowrite = (isiz - numwritten); if (numtowrite > BLOB_BLOCK_SIZE) numtowrite = BLOB_BLOCK_SIZE; dbmoretext(dbprocw, (DBINT) numtowrite, (BYTE *) (blob + numwritten)); } dbsqlok(dbprocw); while (dbresults(dbprocw) != NO_MORE_RESULTS){ printf("suprise!\n"); } } #if 0 if (SUCCEED != dbclose(dbproc)){ fprintf(stdout, "dbclose failed"); exit(1); } dbproc = dbopen(login, SERVER); assert(dbproc); if (strlen(DATABASE)) { dbuse(dbproc, DATABASE); } #endif sql_cmd(dbproc); dbsqlexec(dbproc); if (dbresults(dbproc) != SUCCEED) { failed = 1; fprintf(stdout, "Was expecting a result set."); exit(1); } for (i = 1; i <= dbnumcols(dbproc); i++) { printf("col %d, \"%s\", is type %s\n", i, dbcolname(dbproc, i), dbprtype(dbcoltype(dbproc, i))); } if (2 != dbnumcols(dbproc)) { fprintf(stderr, "Failed. Expected 2 columns\n"); exit(1); } if (SUCCEED != dbbind(dbproc, 1, INTBIND, -1, (BYTE *) & testint)) { fprintf(stderr, "Had problem with bind\n"); exit(1); } if (REG_ROW != dbnextrow(dbproc)) { fprintf(stderr, "Failed. Expected a row\n"); exit(1); } if (testint != 1) { failed = 1; fprintf(stderr, "Failed. Expected i to be %d, was %d\n", 1, (int) testint); exit(1); } dbnextrow(dbproc); /* get the image */ sql_cmd(dbproc); dbsqlexec(dbproc); dbresults(dbproc); fprintf(stdout, "select 2\n"); sql_cmd(dbproc); dbsqlexec(dbproc); if (dbresults(dbproc) != SUCCEED) { fprintf(stderr, "Error extracting blob\n"); return 6; } numread = 0; rblob = NULL; while ((result = dbreadtext(dbproc, rbuf, BLOB_BLOCK_SIZE)) != NO_MORE_ROWS) { if (result != 0) { /* this indicates not end of row */ rblob = (char*) realloc(rblob, result + numread); memcpy((void *) (rblob + numread), (void *) rbuf, result); numread += result; } } data_ok = 1; if (memcmp(blob, rblob, numread) != 0) { printf("Saving first blob data row to file: %s\n", argv[2]); if ((fp = fopen(argv[2], "wb")) == NULL) { fprintf(stderr, "Unable to open output file: %s\n", argv[2]); return 3; } fwrite((void *) rblob, numread, 1, fp); fclose(fp); failed = 1; data_ok = 0; } printf("Read blob data row %d --> %s %ld byte comparison\n", (int) testint, data_ok ? "PASSED" : "failed", numread); free(rblob); if (dbnextrow(dbproc) != NO_MORE_ROWS) { failed = 1; fprintf(stderr, "Was expecting no more rows\n"); exit(1); } free(blob); drop_table(); dbclose(dbproc); dbproc = NULL; dbexit(); return 0; }