int main() { cout << "***OCCI Globalization Support demo program.***" << endl; cout << "***This program loads Unicode data files into a NClob attribute***" << endl; char *unicodefiles[4] = {"occiuni2_hindi.txt", "occiuni2_russian.txt", "occiuni2_korean.txt", "occiuni2_japanese.txt"}; try { cout << "Initializing OCCI environment in Unicode mode" << endl; //initialize in Unicode(UTF16) mode Environment *utf16env = Environment::createEnvironment( "OCCIUTF16", "OCCIUTF16", Environment::OBJECT ); occiuni2m(utf16env); //"L" prefix will create a widechar i.e Unicode literal which is equivalent to // OCCI's UString datatype Connection *conn = utf16env->createConnection( L"hr",L"hr",L"" ); //load the 4 sample Unicode files for (int i = 0; i < 4;i++) { //convert the filename argument to Unicode. We will be saving the filename //as one of the attributes of the object. const char *asciifilename = unicodefiles[i]; wchar_t wcfilename[100]; MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, (LPCSTR)asciifilename, strlen(asciifilename)+1, (LPWSTR)wcfilename, 100 ); wstring docname(wcfilename); cout << "Loading " << asciifilename << endl; //Create a persistent object, set the NClob to empty and save //the object. Use the overloaded new operator that takes UString //arugments DocObjType *newdoc = new (conn, L"DOCUMENTSTAB",L"DOCOBJTYPE", L"HR",L"HR") DocObjType(); newdoc->setDocname(docname); //first insert a empty clob Clob doccontents(conn); doccontents.setEmpty(); newdoc->setDoctext(doccontents);//empty conn->commit(); //Now, we will select the object again and add the document text //to the NClob attribute. Statement *stmt = conn->createStatement( L"select ref(a) from documentstab a where docname = :1 for update"); stmt->setUString(1, docname);//bind wstring ResultSet *rs = stmt->executeQuery(); rs->next();//this will actually fetch the Ref Ref<DocObjType> docobjref = rs->getRef(1); DocObjType *docobj = docobjref.ptr();//pin the object doccontents = docobj->getDoctext();//get the Clob doccontents.open(); doccontents.setCharSetId("OCCIUTF16"); doccontents.setCharSetForm(OCCI_SQLCS_NCHAR); ifstream in( asciifilename, ios::binary ); int bytesread=0, totalbytesread=0, wcharsread=0; wchar_t wbuffer1[50];//50 chars = 100 bytes at a time //we have stored the data in a Unicode text file. The first //character (2 bytes) is a Unicode Byte-Order-Mark and //indicates whether the data in the file is little-endian or //big-endian in.read((char *)wbuffer1,2);//read & skip BOM int offset = 1; while (in.read( (char *)wbuffer1,sizeof(wbuffer1) )) { bytesread = in.gcount(); wcharsread = bytesread/2; //write to the NClob doccontents.writeChunk( wcharsread, (utext *)wbuffer1, sizeof(wbuffer1), offset ); offset += wcharsread;//offset is in terms of characters totalbytesread += bytesread; } //last chunk bytesread = in.gcount(); wcharsread = bytesread/2; totalbytesread += bytesread; doccontents.writeChunk( wcharsread, (utext *)wbuffer1, bytesread, offset ); doccontents.close(); //update the object and flush to database docobj->setDoctext(doccontents); docobj->markModified(); docobj->flush(); conn->commit(); cout << totalbytesread/2 << " characters saved" << endl; //Statement & ResultSet objects will be created again stmt->closeResultSet(rs); conn->terminateStatement(stmt); }//for (i = 0; i < 4) cout << "Now reading the NClob data back and saving to new files" << endl; Statement *selectstmt = conn->createStatement( L"select ref(a) from DocumentsTab a" ); ResultSet *queryrs = selectstmt->executeQuery(); wstring wfilehdrtxt = L"If you cannot see the text properly, try setting your font to a Unicode font like : - Arial Unicode MS, Lucinda Sans Unicode etc..."; while (queryrs->next()) { Ref<DocObjType> docobjref = queryrs->getRef(1); wstring docname = docobjref->getDocname(); //create the output file, prepend "fetch_" to the original filename docname = L"fetch_" + docname; char asciifilenamebuf[100]; int ret = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)docname.c_str(), docname.length()+1, (LPSTR)asciifilenamebuf, 100, NULL, NULL); cout << "Creating Unicode textfile " << asciifilenamebuf << endl; ofstream outdoc(asciifilenamebuf, ios_base::binary | ios_base::trunc); //first write the BOM wchar_t bom = 0xFEFF;//Windows is little-endian outdoc.write((char *)&bom, 2); outdoc.write((char *)wfilehdrtxt.c_str(), wfilehdrtxt.length()*2); Clob doccontents = docobjref->getDoctext(); doccontents.setCharSetId("OCCIUTF16"); doccontents.setCharSetForm(OCCI_SQLCS_NCHAR); int offset = 1; int clobcharsread=0; //now read the NClob and write to file wchar_t wbuffer2[100];//100 chars at a time while ( (clobcharsread = doccontents.read(100, wbuffer2, sizeof(wbuffer2), offset)) !=0 ) { offset = offset+clobcharsread; outdoc.write((char *)wbuffer2,clobcharsread*2);//write takes number of bytes } outdoc.close(); }//while (queryrs->next()) //done cout << "You can view the created files in Notepad(or any other editor that displays Unicode)" << endl; selectstmt->closeResultSet(queryrs); conn->terminateStatement(selectstmt); //delete the rows from the table //if you want to retain the rows, comment out cout << "Cleaning up table" << endl; Statement *deletestmt = conn->createStatement( L"delete from DocumentsTab"); deletestmt->executeUpdate(); conn->commit(); utf16env->terminateConnection(conn); Environment::terminateEnvironment(utf16env); cout << "Done" << endl; } catch (SQLException &e) { std::cout << e.getErrorCode() << std::endl; } return 0; }