pike.git / lib / modules / Sql.pmod / tds.pike

version» Context lines:

pike.git/lib/modules/Sql.pmod/tds.pike:1:   /* -  * $Id: tds.pike,v 1.4 2006/02/10 10:31:44 grubba Exp $ +  * $Id: tds.pike,v 1.5 2006/02/10 13:08:43 grubba Exp $    *    * A Pike implementation of the TDS protocol.    *    * Henrik Grubbström 2006-02-08.    */      #define TDS_DEBUG      #ifdef TDS_DEBUG   #define TDS_WERROR(X...) werror("TDS:" + X)
pike.git/lib/modules/Sql.pmod/tds.pike:173:    TDS_DONEINPROC_RESULT = 4054,    };       string server_data;    string last_error;    array(mapping(string:mixed)) column_info;       void tds_error(string msg, mixed ... args)    {    if (sizeof(args)) msg = sprintf(msg, @args); -  error(last_error = msg); +  predef::error(last_error = msg);    }       static object utf16enc = Locale.Charset.encoder("UTF16LE");    static string string_to_utf16(string s)    {    return utf16enc->feed(s)->drain();    }    static object utf16dec = Locale.Charset.decoder("UTF16LE");    static string utf16_to_string(string s)    {
pike.git/lib/modules/Sql.pmod/tds.pike:214:    Stdio.File socket;      #define FMT_SMALLINT "%-2c"   #define FMT_INT "%-4c"   #define FMT_INT8 "%-4c"       int inpos = 0;    string inbuf = "";    static void fill_buf()    { +  if (!busy) { +  TDS_WERROR("Filling buffer on idle connection!\n"); +  } +     string header = socket->read(8);    if (!header || sizeof(header) < 8) {    tds_error("Failed to read packet header: %O, %s.\n",    header, strerror(socket->errno()));    }    TDS_WERROR("Read header:\n%s\n", hex_dump(header));    int packet_type;    int last_packet;    int len;    // NOTE: Network byteorder!!    sscanf(header, "%-1c%-1c%2c", packet_type, last_packet, len);    len -= 8; -  +  +  busy = !last_packet; +     string data = socket->read(len);    if (!data || sizeof(data) < len) {    tds_error("Failed to read packet data (%d bytes), got %O (%d bytes), %s\n",    len, data, sizeof(data||""), strerror(socket->errno()));    }    TDS_WERROR("Read packet with %d bytes.\n%s\n",    sizeof(data), hex_dump(data));    inbuf = inbuf[inpos..] + data;    inpos = 0;    }
pike.git/lib/modules/Sql.pmod/tds.pike:410:    res, sizeof(res));    if (!flags) return res;    return sprintf("%-4c%s", sizeof(res)+4, res);    }    }       static void send_packet(Packet p, int flag, int|void last)    {    string raw = (string) p;    +  if (busy) { +  TDS_WERROR("Sending packet on busy connection!\n"); +  } +  if (sizeof(inbuf) > inpos) { +  TDS_WERROR("inbuf: %O\n" +  "%s\n", +  inbuf[inpos..], +  hex_dump(inbuf[inpos..])); +  } +  inbuf = ""; +  inpos = 0; +  busy = last; +  +  // FIXME: Split large packets! +     // NOTE: Network byteorder!!    raw =    sprintf("%-1c%-1c%2c\0\0%-1c\0%s",    flag, last,    sizeof(raw) + 8,    1, /* TDS 7 or 8. */    (string)raw);    TDS_WERROR("Wrapped packet: %O\n%s\n", raw, hex_dump(raw));    if (socket->write(raw) != sizeof(raw)) {    tds_error("Failed to send packet.\n"
pike.git/lib/modules/Sql.pmod/tds.pike:832:    static void tds7_process_result()    {    int num_cols = get_smallint();    if (num_cols == 0xffff) {    TDS_WERROR("No meta data.\n");    column_info = 0;    return;    }    TDS_WERROR("%d columns in result.\n", num_cols);    column_info = allocate(num_cols); -  busy = 1; +  //busy = 1;    int offset = 0;    foreach(column_info; int col; ) {    column_info[col] = tds7_get_data_info();    column_info[col]->column_offset = offset;    TDS_WERROR("Offset: 0x%04x\n", offset);    if (is_numeric_type(column_info[col]->cardinal_type)) {    offset += 35; // sizeof(TDS_NUMERIC)    } else if (is_blob_type(column_info[col]->cardinal_type)) {    offset += 32; // sizeof(TDSBLOB)    } else {
pike.git/lib/modules/Sql.pmod/tds.pike:907:    TDS_WERROR("TDS_TABNAME_TOKEN\n");    process_default_tokens(get_byte());    if (peek_byte() == TDS_COLINFO_TOKEN) {    TDS_WERROR("TDS_COLINFO_TOKEN\n");    get_byte();    //process_colinfo(); // FIXME!    }    }    TDS_WERROR("==> TDS_ROWFMT_RESULT\n");    return TDS_ROWFMT_RESULT; +  case TDS_DONE_TOKEN:    case TDS_ROW_TOKEN:    TDS_WERROR("==> TDS_ROW_RESULT\n");    return TDS_ROW_RESULT;    default:    get_byte();    TDS_WERROR("==> FIXME: process_result_tokens\n");    process_default_tokens(token_type);    return 0; /***** FIXME:::::: *****/    break;    }
pike.git/lib/modules/Sql.pmod/tds.pike:982:    string raw = get_raw(colsize);    TDS_WERROR("BLOB. colsize:%d, raw: %O\n", colsize, raw);    if (is_char_type(info->cardinal_type)) {    return utf16_to_string(raw);    }    return raw;    } else {    string raw = get_raw(colsize);    TDS_WERROR("Got raw data: %O\ncolumn_size:%d colsize:%d\n%s\n",    raw, info->column_size, colsize, hex_dump(raw)); +  if (is_unicode_type(info->column_type)) { +  raw = utf16_to_string(raw); +  }    if (colsize < info->column_size) {    // Handle padding.    switch(info->cardinal_type) {    case SYBLONGBINARY:    // FIXME: ??    break;    case SYBCHAR:    case XSYBCHAR:    raw += " "*(info->column_size - colsize);    break;
pike.git/lib/modules/Sql.pmod/tds.pike:1062:    case SYBFLT8:    case SYBUNIQUE:    default:    // FIXME:    TDS_WERROR("Not yet supported: %d\n", info->cardinal_type);    return raw;    case SYBBIT:    case SYBBITN:    return raw[0]?"1":"0";    case SYBINT1: -  // FIXME: SIGN! -  return sprintf("%d", array_sscanf(raw, "%-1c")[0]); +     case SYBINT2: -  // FIXME: SIGN! -  return sprintf("%d", array_sscanf(raw, "%-2c")[0]); +     case SYBINT4: -  // FIXME: SIGN! -  return sprintf("%d", array_sscanf(raw, "%-4c")[0]); +     case SYBINT8: -  // FIXME: SIGN! -  return sprintf("%d", array_sscanf(raw, "%-8c")[0]); +  case SYBINTN: +  { +  int val; +  if (raw[-1]& 0x80) { +  // Negative. +  val = ~array_sscanf((~raw) + ("\x00"*8), "%-8c")[0]; +  } else { +  val = array_sscanf(raw + ("\x00"*8), "%-8c")[0]; +  } +  TDS_WERROR("Converted %O ==> %d\n", raw, val); +  return sprintf("%d", val); +  }    case SYBDATETIMN:    if (sizeof(raw) == 8) cardinal_type = SYBDATETIME;    // FALL_THROUGH    case SYBDATETIME:    case SYBDATETIME4:    {    int day, min, sec, sec_300;    if (cardinal_type == SYBDATETIME) {    sscanf(raw, "%-4c%-4c", day, sec_300);    sec = sec_300/300;
pike.git/lib/modules/Sql.pmod/tds.pike:1125:    if (!column_info) return 0;    array(string|int) res = allocate(sizeof(column_info));    foreach(column_info; int i; mapping(string:mixed) info) {    res[i] = convert(get_data(info, i), info);    }    return res;    }       array(string|int) process_row_tokens(int|void leave_end_token)    { -  if (!busy) return 0; // No more rows. +  //if (!busy) return 0; // No more rows.    while (1) {    int token_type = peek_byte();    TDS_WERROR("Process row tokens: Token type: %d\n", token_type);    switch(token_type) {    case TDS_RESULT_TOKEN:    case TDS_ROWFMT2_TOKEN:    case TDS7_RESULT_TOKEN:    // Some other result starts here. -  busy = 0; +  //busy = 0;    return 0;    case TDS_ROW_TOKEN:    get_byte();    return process_row();    break;    case TDS_DONE_TOKEN:    case TDS_DONEPROC_TOKEN:    case TDS_DONEINPROC_TOKEN:    if (!leave_end_token) get_byte(); -  busy = 0; +  //busy = 0;    return 0;    default:    get_byte();    process_default_tokens(token_type);    break;    }    }    }       static void process_login_tokens()
pike.git/lib/modules/Sql.pmod/tds.pike:1380:    j = i+1;    break;    }    }    res += ({ query[j..] });    return map(res, string_to_utf16);    }       static void create(string query)    { +  TDS_WERROR("Compiling query: %O\n", query);    splitted_query = split_query_on_placeholders(query);    n_param = sizeof(splitted_query)-1;    }   }      class big_query   {    static int row_no;    static int eot;   
pike.git/lib/modules/Sql.pmod/tds.pike:1420:    }    Execute(query);    }   }      string server_info()   {    return server_data;   }    + string error() + { +  return last_error; + } +    static void create(string|void server, string|void database,    string|void user, string|void pwd)   {    if (con) {    Disconnect();    }    int port = DEF_PORT;    if (server) {    array(string) tmp = server/":";    if (sizeof(tmp) > 1) {    port = (int)tmp[-1];    server = tmp[..sizeof(tmp)-2]*":";    }    } else {    server = "127.0.0.1";    }    Connect(server, port, database || "default",    user || "", pwd || "");   }