node-odbc icon indicating copy to clipboard operation
node-odbc copied to clipboard

Blob handling

Open RocketRooster opened this issue 10 years ago • 2 comments

Hi there Dan,

I have no idea how this forking/pulling malarkey works so please pardon me if this belongs elsewhere.

I've made the following hack to odbc.cpp to enable storing and retrieval of blob data. It works but I don't know if it's reliable. My environment is DB2 Express-C 10.5 running on Ubuntu 12.04.

odbc.cpp

1) Added a define

#define SQL_DB2_BLOB (-98)

2) I've added the following case(s) to ODBC::GetColumnValue.

note: I don't actually know if anything other than -98 for the application buffer type is ever returned and haven't tested any of the following either or even whether they are appropriate:

  • SQL_LONGVARBINARY :
  • SQL_VARBINARY :
  • SQL_BINARY :
  • SQL_WCHAR :
  • SQL_WVARCHAR :
  • SQL_WLONGVARCHAR :
    case SQL_DB2_BLOB :

      ret = SQLGetData(
        hStmt,
        column.index,
        SQL_C_BINARY,
        (char *) buffer,
        bufferLength,
        &len);

      DEBUG_PRINTF("ODBC::GetColumnValue - BINARY: index=%lld name=%s type=%lld len=%lld\n",
                    column.index, column.name, column.type, len);

      if (len == SQL_NULL_DATA) {
        return scope.Close(Null());
      }
      else {
        // construct slowbuffer to return to nodejs
        node::Buffer *slowBuffer = node::Buffer::New(bufferLength);
        memcpy(node::Buffer::Data(slowBuffer), buffer, bufferLength);
        v8::Local<v8::Object> globalObj = v8::Context::GetCurrent()->Global();
        v8::Local<v8::Function> buffConstr = v8::Local<v8::Function>::Cast(globalObj->Get(v8::String::New("Buffer")));
        v8::Handle<v8::Value> constructorArgs[3] = { slowBuffer->handle_, v8::Integer::New(bufferLength), v8::Integer::New(0) };
        v8::Local<v8::Object> retBuff = buffConstr->NewInstance(3, constructorArgs);

        // what should follow this bit here I dunno about, do I need to do anything special to buffer
        // like releasing it and what have you?


        // return buffer
        return scope.Close(retBuff);
      } break;

3) Added the following test to ODBC::GetParametersFromArray.

    else if (value->IsObject()) {
      params[i].ValueType         = SQL_C_BINARY;
      params[i].ParameterType     = SQL_VARBINARY;
      params[i].ParameterValuePtr = node::Buffer::Data(value);
      params[i].BufferLength      = node::Buffer::Length(value);
      params[i].StrLen_or_IndPtr  = params[i].BufferLength;
      params[i].ColumnSize        = 0;

      DEBUG_PRINTF("ODBC::GetParametersFromArray - IsObject(): params[%lld] "
                   "c_type=%lld type=%lld buffer_length=%lld size=%lld length=%lld\n",
                   i, params[i].ValueType, params[i].ParameterType,
                   params[i].BufferLength, params[i].ColumnSize, params[i].StrLen_or_IndPtr);
    }

All in all, it returns nodejs buffers for blob columns and allows you to pass buffers to stored procedures.

But PLEASE take a look whether it's correct, I'm a noob! If you're happy with it I'd love for it to become part of the code base because at the moment I need to edit and rebuild every time I do an update of node-odbc.

Cheers! Riaan

RocketRooster avatar Jul 17 '15 07:07 RocketRooster

Hopefully I'll get some time to take a closer look at this soon.

wankdanker avatar Jul 31 '15 17:07 wankdanker

@RocketRooster, I couldn't find your commits for your buffer support. I couldn't find a node-odbc branch on your github account either. Are you still interested in getting this merged?

wankdanker avatar Sep 25 '15 19:09 wankdanker