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_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 pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options) { pdo_dblib_db_handle *H; int i, nvars, nvers, ret = 0; const pdo_dblib_keyval tdsver[] = { {"4.2",DBVERSION_42} ,{"4.6",DBVERSION_46} ,{"5.0",DBVERSION_70} /* FIXME: This does not work with Sybase, but environ will */ ,{"6.0",DBVERSION_70} ,{"7.0",DBVERSION_70} #ifdef DBVERSION_71 ,{"7.1",DBVERSION_71} #endif #ifdef DBVERSION_72 ,{"7.2",DBVERSION_72} ,{"8.0",DBVERSION_72} #endif #ifdef DBVERSION_73 ,{"7.3",DBVERSION_73} #endif #ifdef DBVERSION_74 ,{"7.4",DBVERSION_74} #endif ,{"10.0",DBVERSION_100} ,{"auto",0} /* Only works with FreeTDS. Other drivers will bork */ }; struct pdo_data_src_parser vars[] = { { "charset", NULL, 0 } ,{ "appname", "PHP " PDO_DBLIB_FLAVOUR, 0 } ,{ "host", "127.0.0.1", 0 } ,{ "dbname", NULL, 0 } ,{ "secure", NULL, 0 } /* DBSETLSECURE */ ,{ "version", NULL, 0 } /* DBSETLVERSION */ }; nvars = sizeof(vars)/sizeof(vars[0]); nvers = sizeof(tdsver)/sizeof(tdsver[0]); php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars); H = pecalloc(1, sizeof(*H), dbh->is_persistent); H->login = dblogin(); H->err.sqlstate = dbh->error_code; H->stringify_uniqueidentifier = 0; if (!H->login) { goto cleanup; } if (driver_options) { int connect_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT, -1); int query_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_QUERY_TIMEOUT, -1); int timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30); if (connect_timeout == -1) { connect_timeout = timeout; } if (query_timeout == -1) { query_timeout = timeout; } dbsetlogintime(connect_timeout); /* Connection/Login Timeout */ dbsettime(query_timeout); /* Statement Timeout */ H->stringify_uniqueidentifier = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, 0); } DBERRHANDLE(H->login, (EHANDLEFUNC) pdo_dblib_error_handler); DBMSGHANDLE(H->login, (MHANDLEFUNC) pdo_dblib_msg_handler); if(vars[5].optval) { for(i=0;i<nvers;i++) { if(strcmp(vars[5].optval,tdsver[i].key) == 0) { if(FAIL==dbsetlversion(H->login, tdsver[i].value)) { pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Failed to set version specified in connection string."); goto cleanup; } break; } } if (i==nvers) { printf("Invalid version '%s'\n", vars[5].optval); pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Invalid version specified in connection string."); goto cleanup; /* unknown version specified */ } } if (dbh->username) { if(FAIL == DBSETLUSER(H->login, dbh->username)) { goto cleanup; } } if (dbh->password) { if(FAIL == DBSETLPWD(H->login, dbh->password)) { goto cleanup; } } #if !PHP_DBLIB_IS_MSSQL if (vars[0].optval) { DBSETLCHARSET(H->login, vars[0].optval); } #endif DBSETLAPP(H->login, vars[1].optval); /* DBSETLDBNAME is only available in FreeTDS 0.92 or above */ #ifdef DBSETLDBNAME if (vars[3].optval) { if(FAIL == DBSETLDBNAME(H->login, vars[3].optval)) goto cleanup; } #endif H->link = dbopen(H->login, vars[2].optval); if (!H->link) { goto cleanup; } /* * FreeTDS < 0.92 does not support the DBSETLDBNAME option * Send use database here after login (Will not work with SQL Azure) */ #ifndef DBSETLDBNAME if (vars[3].optval) { if(FAIL == dbuse(H->link, vars[3].optval)) goto cleanup; } #endif #if PHP_DBLIB_IS_MSSQL /* dblib do not return more than this length from text/image */ DBSETOPT(H->link, DBTEXTLIMIT, "2147483647"); #endif /* limit text/image from network */ DBSETOPT(H->link, DBTEXTSIZE, "2147483647"); /* allow double quoted indentifiers */ DBSETOPT(H->link, DBQUOTEDIDENT, "1"); ret = 1; dbh->max_escaped_char_length = 2; dbh->alloc_own_columns = 1; cleanup: for (i = 0; i < nvars; i++) { if (vars[i].freeme) { efree(vars[i].optval); } } dbh->methods = &dblib_methods; dbh->driver_data = H; if (!ret) { zend_throw_exception_ex(php_pdo_get_exception(), DBLIB_G(err).dberr, "SQLSTATE[%s] %s (severity %d)", DBLIB_G(err).sqlstate, DBLIB_G(err).dberrstr, DBLIB_G(err).severity); } return ret; }
int main(int argc, char *argv[]) { int echo = 0; #ifdef notyet int print_statistics = 0; #endif int fipsflagger = 0; int perfstats = 0; int use_encryption = 0; int chained_transactions = 0; int headers = 0; char *columnwidth = NULL; const char *colseparator = " "; const char *lineseparator = "\n"; int timeout = 0; char *username = NULL; char *password = NULL; char *server = NULL; DBCHAR *char_set = NULL; char *hostname = NULL; char *interfaces_filename = NULL; char *input_filename = NULL; char *output_filename = NULL; int logintime = -1; char *language = NULL; int size = 0; char *sybenv; LOGINREC *login; int printedlines; int i; int dbrc; int c; int errflg = 0; char *prbuf; int prbuflen; int num_cols; int selcol; int col; int collen; DBINT colid; const char *opname; char adbuf[512]; DBINT convlen; int printedcompute = 0; char adash; const char *database_name = NULL; setlocale(LC_ALL, ""); #ifdef __VMS /* Convert VMS-style arguments to Unix-style */ parse_vms_args(&argc, &argv); #endif editor = getenv("EDITOR"); if (!editor) { editor = getenv("VISUAL"); } if (!editor) { editor = "vi"; } opterr = 0; optarg = NULL; while (!errflg && (c = getopt(argc, argv, "eFgpnvXYa:c:D:E:h:H:i:I:J:l:m:o:P:s:S:t:U:w:y:z:A:")) != -1) { switch (c) { case 'e': echo = 1; break; case 'F': fipsflagger = 1; break; case 'g': errflg++; break; case 'p': errflg++; perfstats = 1; break; case 'n': no_prompt = 1; break; case 'v': puts("fisql, a free isql replacement by Nicholas S. Castellano"); return EXIT_SUCCESS; break; case 'X': /* XXX: We get a different error message than isql gives; neither seems * to work */ use_encryption = 1; break; case 'Y': chained_transactions = 1; break; case 'c': cmdend = optarg; break; case 'E': editor = optarg; break; case 'h': headers = atoi(optarg); break; case 'H': hostname = optarg; break; case 'i': input_filename = optarg; break; case 'I': interfaces_filename = optarg; break; case 'J': errflg++; break; case 'l': logintime = atoi(optarg); break; case 'm': global_errorlevel = atoi(optarg); break; case 'o': output_filename = optarg; break; case 'P': password = optarg; break; case 's': colseparator = optarg; break; case 'S': server = optarg; break; case 't': timeout = atoi(optarg); break; case 'U': username = optarg; break; case 'w': columnwidth = optarg; break; case 'y': /* XXX: this doesn't seem to be what isql does with -y...it doesn't * seem to do anything actually */ sybenv = (char *) xmalloc((strlen(optarg) + 8) * sizeof(char)); strcpy(sybenv, "SYBASE="); strcat(sybenv, optarg); putenv(sybenv); break; case 'z': language = optarg; break; case 'A': size = atoi(optarg); break; case 'D': database_name = optarg; break; default: errflg++; break; } } if (errflg) { fprintf(stderr, "usage: fisql [-e] [-F] [-g] [-p] [-n] [-v] [-X] [-Y]\n"); fprintf(stderr, "\t[-c cmdend] [-D database_name] [-E editor]\n"); fprintf(stderr, "\t[-h headers] [-H hostname] [-i inputfile]\n"); fprintf(stderr, "\t[-I interfaces_file] [-J client character set]\n"); fprintf(stderr, "\t[-l login_timeout] [-m errorlevel]\n"); fprintf(stderr, "\t[-o outputfile]\n"); fprintf(stderr, "\t[-P password] [-s colseparator] [-S server]\n"); fprintf(stderr, "\t[-t timeout] [-U username] [-w columnwidth]\n"); fprintf(stderr, "\t[-y sybase_dir] [-z language]\n"); return EXIT_FAILURE; } if (!(isatty(fileno(stdin)))) { no_prompt = 1; rl_outstream = fopen("/dev/null", "rw"); } rl_readline_name = "fisql"; rl_bind_key('\t', rl_insert); if (password == NULL) { password = (char *) xmalloc(READPASSPHRASE_MAXLEN); readpassphrase("Password: "******"r", stdin) == NULL) { /* XXX: sybase isql generates this error while parsing the options, * but doesn't redirect the input until after the Password: prompt */ /* lack of newline for bug-compatibility with isql */ fprintf(stderr, "Unable to open input file '%s'.", optarg); return EXIT_FAILURE; } } if (output_filename) { if (freopen(output_filename, "w", stdout) == NULL) { /* XXX: sybase isql generates this error while parsing the options, * but doesn't redirect the output until after the Password: prompt */ /* lack of newline for bug-compatibility with isql */ fprintf(stderr, "Unable to open output file '%s'.", output_filename); return EXIT_FAILURE; } } if (isatty(fileno(stdin))) { rl_outstream = stdout; } dbinit(); #if 0 #ifdef DBVERSION_100 dbsetversion(DBVERSION_100); #endif #endif if ((login = dblogin()) == NULL) { reset_term(); return EXIT_FAILURE; } dbmsghandle(msg_handler); dberrhandle(err_handler); DBSETLAPP(login, "fisql"); if (username) { DBSETLUSER(login, username); } DBSETLPWD(login, password); memset(password, 0, strlen(password)); if (char_set) { DBSETLCHARSET(login, char_set); } if (use_encryption) { DBSETLENCRYPT(login, TRUE); } if (hostname) { DBSETLHOST(login, hostname); } if (language) { DBSETLNATLANG(login, language); } if (size) { DBSETLPACKET(login, (short) size); } if (interfaces_filename) { dbsetifile(interfaces_filename); } dbsettime(timeout); if (logintime >= 0) { dbsetlogintime(logintime); } if (database_name) { DBSETLDBNAME(login, database_name); } if ((dbproc = dbopen(login, server)) == NULL) { fprintf(stderr, "fisql: dbopen() failed.\n"); reset_term(); return EXIT_FAILURE; } dbsetopt(dbproc, DBPRLINESEP, lineseparator, strlen(lineseparator)); if (colseparator) { dbsetopt(dbproc, DBPRCOLSEP, colseparator, strlen(colseparator)); } if (columnwidth) { dbsetopt(dbproc, DBPRLINELEN, columnwidth, 0); } if (chained_transactions) { dbsetopt(dbproc, DBCHAINXACTS, NULL, 0); } if (fipsflagger) { dbsetopt(dbproc, DBFIPSFLAG, NULL, 0); } if (perfstats) { dbsetopt(dbproc, DBSTAT, "time", 0); } while (1) { if (sigsetjmp(restart, 1)) { reset_ibuf(); fputc('\n', stdout); rl_on_new_line(); rl_reset_line_state(); } dbcancel(dbproc); signal(SIGINT, inactive_interrupt_handler); read_sql_lines(); dbfreebuf(dbproc); for (i = 0; i < ibuflines; i++) { if (echo) { puts(ibuf[i]); } dbcmd(dbproc, ibuf[i]); dbcmd(dbproc, "\n"); free(ibuf[i]); } free(ibuf); ibuf = NULL; signal(SIGINT, active_interrupt_handler); dbsetinterrupt(dbproc, (void *) active_interrupt_pending, (void *) active_interrupt_servhandler); if (dbsqlexec(dbproc) == SUCCEED) { int status_printed = 0; maybe_handle_active_interrupt(); while ((dbrc = dbresults(dbproc)) != NO_MORE_RESULTS) { printedlines = 0; #define USE_DBPRROW 0 #if USE_DBPRROW dbprhead(dbproc); dbprrow(dbproc); #else if ((dbrc == SUCCEED) && (DBROWS(dbproc) == SUCCEED)) { prbuflen = dbspr1rowlen(dbproc); prbuf = (char *) xmalloc(prbuflen * sizeof(char)); dbsprhead(dbproc, prbuf, prbuflen); fputs(prbuf, stdout); fputc('\n', stdout); dbsprline(dbproc, prbuf, prbuflen, '-'); fputs(prbuf, stdout); fputc('\n', stdout); maybe_handle_active_interrupt(); while ((dbrc = dbnextrow(dbproc)) != NO_MORE_ROWS) { if (dbrc == FAIL) { break; } if (dbrc != REG_ROW) { num_cols = dbnumalts(dbproc, dbrc); for (selcol = col = 1; col <= num_cols; col++) { colid = dbaltcolid(dbproc, dbrc, col); while (selcol < colid) { collen = get_printable_column_size(dbproc, selcol); for (i = 0; i < collen; i++) { putchar(' '); } selcol++; printf("%s", colseparator); } opname = dbprtype(dbaltop(dbproc, dbrc, col)); printf("%s", opname); collen = get_printable_column_size(dbproc, colid); collen -= strlen(opname); while (collen-- > 0) { putchar(' '); } selcol++; printf("%s", colseparator); } printf("%s", lineseparator); for (selcol = col = 1; col <= num_cols; col++) { colid = dbaltcolid(dbproc, dbrc, col); while (selcol < colid) { collen = get_printable_column_size(dbproc, selcol); for (i = 0; i < collen; i++) { putchar(' '); } selcol++; printf("%s", colseparator); } collen = get_printable_column_size(dbproc, colid); adash = '-'; for (i = 0; i < collen; i++) { putchar(adash); } selcol++; printf("%s", colseparator); } printf("%s", lineseparator); for (selcol = col = 1; col <= num_cols; col++) { colid = dbaltcolid(dbproc, dbrc, col); while (selcol < colid) { collen = get_printable_column_size(dbproc, selcol); for (i = 0; i < collen; i++) { putchar(' '); } selcol++; printf("%s", colseparator); } convlen = dbconvert(dbproc, dbalttype(dbproc, dbrc, col), dbadata(dbproc, dbrc, col), dbadlen(dbproc, dbrc, col), SYBCHAR, (BYTE *) adbuf, sizeof(adbuf)); printf("%.*s", (int) convlen, adbuf); collen = get_printable_column_size(dbproc, colid); collen -= convlen; while (collen-- > 0) { putchar(' '); } selcol++; printf("%s", colseparator); } printf("%s", lineseparator); printedcompute = 1; continue; } if (printedcompute || (headers && (printedlines >= headers) && ((printedlines % headers) == 0))) { fputc('\n', stdout); dbsprhead(dbproc, prbuf, prbuflen); fputs(prbuf, stdout); fputc('\n', stdout); dbsprline(dbproc, prbuf, prbuflen, '-'); fputs(prbuf, stdout); fputc('\n', stdout); printedcompute = 0; } printedlines++; dbspr1row(dbproc, prbuf, prbuflen); fputs(prbuf, stdout); fputc('\n', stdout); maybe_handle_active_interrupt(); } fputc('\n', stdout); free(prbuf); maybe_handle_active_interrupt(); } #endif if (dbrc != FAIL) { if ((DBCOUNT(dbproc) >= 0) || dbhasretstat(dbproc)) { if (DBCOUNT(dbproc) >= 0) { fprintf(stdout, "(%d rows affected", (int) DBCOUNT(dbproc)); if (dbhasretstat(dbproc)) { status_printed = 1; dbrc = dbretstatus(dbproc); fprintf(stdout, ", return status = %d", dbrc); } fprintf(stdout, ")\n"); } else { if (dbhasretstat(dbproc)) { status_printed = 1; dbrc = dbretstatus(dbproc); fprintf(stdout, "(return status = %d)\n", dbrc); } } } } } if (!status_printed && dbhasretstat(dbproc)) { dbrc = dbretstatus(dbproc); fprintf(stdout, "(return status = %d)\n", dbrc); } } else { /* Something failed, so change the default * exit status to reflect that. */ default_exit = EXIT_FAILURE; } } reset_term(); dbexit(); return EXIT_FAILURE; }