Accessing smart large objects in nondefault sbspaces

One way to access smart large objects in nondefault spaces is to call the client-side DataBlade® API functions that create, initialize, and set the column-level characteristics of a large object specification structure and then pass a pointer to this structure (MI_LO_SPEC *LO_spec) to the overloaded function.
ITBool CreateLO( MI_LO_SPEC *LO_spec,
                     int flags=IT_LO_WRONLY | IT_LO_APPEND) ;

A better way is to introduce a new C++ class to encapsulate a large object specification structure and possibly modify the existing ITLargeObjectManager class to support passing the column-level storage characteristics of smart large objects as encapsulated C++ objects for use by ITLargeObjectManager::CreateLO.

Here is a description of the short-term solution. Before calling CreateLO, the following DataBlade® API call sets the fields of LO_spec to the column-level storage characteristics of column dolmdolm1.testdata, which is the CLOB column:
res = mi_lo_colinfo_by_name(miconn,
                                   (const char *)"dolmdolm1.testdata",
                                   LO_spec);

Among the attributes for column testdata is the sbspace location specified by the PUT clause when table dolmdolm1 is created. The smart large object location attribute is used by CreateLO (which calls DataBlade® API function mi_lo_create()) when it creates the smart large object.

Here is the complete, modified test case with the new solution:
>>>>>>>>>>>> Begin modified test case with new solution >>>>>>>>>>>>
#include <stdlib.h>
#include <iostream.h>
#include <it.h>
int
main(int argc, const char *argv[])
{
    ITDBInfo dbinfo;
    ITConnection conn;
    char buf[1024];
    int i;
    ITString types[2];
    ITString sqlcmd;
    types[0] = "VARCHAR";
    types[1] = "VARCHAR";
    cout << " INFORMIXSERVER   : ";
    cin.getline(buf, sizeof(buf));
    if (!dbinfo.SetSystem(buf)){
            cout << "Could not set system " << endl;
        return (1);
    }
    cout << " DATABASE : ";
    cin.getline(buf, sizeof(buf));
    if (!dbinfo.SetDatabase(buf)){
            cout << "Could not set database " << endl;
            return (1);
    }
    cout << " USER     : ";
    cin.getline(buf, sizeof(buf));
    if (!dbinfo.SetUser(buf)){
            cout << "Could not set user " << endl;
            return (1);
    }
    cout << " PASSWORD : ";
    cin.getline(buf, sizeof(buf));
    if (!dbinfo.SetPassword(buf)){
            cout << "Could not set password " << endl;
            return (1);
    }
    if (!conn.Open(dbinfo) || conn.Error()) {
    if (!conn.Open() || conn.Error()) {
            cout << "Could not open database " << endl;
            return (1);
    }
    cout << "Start Transaction ..." << endl;
    if (!conn.SetTransaction(ITConnection::Begin)) {
            cout << "Could not start transaction " << endl;
            return (1);
    }

   ITStatement stmt(conn);
    cout << " SBLOBSPACE : ";
    cin.getline(buf, sizeof(buf));
    sqlcmd = "create table dolmdolm1 (";
    sqlcmd.Append("uid integer primary key,");
    sqlcmd.Append("testdata CLOB)");
    sqlcmd.Append(" PUT testdata in (");
    sqlcmd.Append(buf);
    sqlcmd.Append(") lock mode row;");
    cout << sqlcmd << endl;
    if (stmt.Error()) {
            cout << "Could not create statement " << endl;
            return (1);
    }
    if (!stmt.Prepare(sqlcmd)) {
            cout << "Could not prepare create statement " << endl;
            return (1);
    }
    if (!stmt.Exec())  {
            cout << "Could not execute create statement " << endl;
            return (1);
    }
    if (!stmt.Drop()) {
            cout << "Could not drop create statement " << endl;
            return (1);
    }
    cout << "Please monitor your sblobspaces, [return to continue]";
    cin.getline(buf, sizeof(buf));
    /************* begin new solution code **************************/
    MI_LO_SPEC *LO_spec = NULL;
    MI_CONNECTION *miconn = NULL;
    mi_integer res;
    ITLargeObjectManager lo(conn);

    miconn = conn.GetConn();
    if (miconn != NULL)
    {
       res = mi_lo_spec_init(miconn, &LO_spec);
       if (res == MI_ERROR)
       {
          cout << "stmt_test: mi_lo_spec_init failed!" << endl;
          return (1);
       }
       res = mi_lo_colinfo_by_name(miconn,
                                   (const char *)"dolmdolm1.testdata",
                                   LO_spec);
       if (res != MI_ERROR)
       {
           cout << endl << "Create a large object. Please wait ..." <<
           endl;

           ITBool status = false;
           status = lo.CreateLO(LO_spec, IT_LO_WRONLY | IT_LO_APPEND);
           if (status = true)
           {
              for (i = 0; i < 1000; i++)
                  lo.Write("1234567890123456789012345678901234567890123456789
                  012345678901234567890123456789012345678901234567890",100);
           }
           else
       {
              cout << "stmt_test: CreateLO w/non-default sbspace
              failed!" <<
              endl;
              return (1);
           }
       }
       else
       {
          cout << "stmt_test: mi_lo_colinfo_by_name failed!" << endl;
          return (1);
       }
    }
    else
    {
       cout << "stmt_test: conn.GetConn returned NULL!" << endl;
       return (1);
    }
    /************* end new solution code **************************/
    cout << "The default sblobspace has changed" << endl;
    cout << "Please monitor your sblobspaces, [return to continue]";
    cin.getline(buf, sizeof(buf));

    cout << endl << "inserting row into dolmdolm1" << endl;
    if (!stmt.Prepare("insert into dolmdolm1 values (?,?);",2,types))
    {
            cout << "Could not prepare insert cursor " << endl;
            return (1);
    }
    ITValue *param;
    param = stmt.Param(0);
    param->FromPrintable("0");
    param->Release();
    param = stmt.Param(1);
    param->FromPrintable(lo.HandleText());
    param->Release();
    if (!stmt.Exec())  {
            cout << "Could not execute insert statement " << endl;
            return (1);
    }
    if (!stmt.Drop()) {
            cout << "Could not drop insert statement " << endl;
            return (1);
    }
    cout << endl;
    cout << "Please monitor your sblobspaces." << endl;
    cout << "The large object is still stored within the default
    sblobspace." << endl;
    cout << "[return to continue]";
    cin.getline(buf, sizeof(buf));
   /*
    cout << "Rollback Transaction ..." << endl;
    if (!conn.SetTransaction(ITConnection::Abort)) {
            cout << "Could not rollback transaction " << endl;
            return (1);
    }
   */
    cout << "Commit Transaction ..." << endl;
    if (!conn.SetTransaction(ITConnection::Commit)) {
            cout << "Could not commit transaction " << endl;
            return (1);
    }
    conn.Close();
    cout << endl;
    return 0;
}
>>>>>>>>>>>> End modified test case with new solution >>>>>>>>>>>>>>