Saturday, March 28, 2009

Oracle with wxWidgets

The second on the list

The source is too a C++ library. I use it for Oracle connections.

If you read the source code and compare it with "Postgres with wxWidgets", now you'll see that are similar and can be adapted to other databases. If you work with MySql and you know the headers and libraries files, you can replace some parts of code to adapt the library to your database.

To use this library in run time, a Oracle instant client is enought, but it should work with any other oracle client.

This source was tested in Windows XP SP2, RedHat 4 and Fedora 8, 9 y 10

You need the Oracle headers:
occiCommon.h, oci1.h, ocidem.h, ocixmldb.h, orl.h, occiControl.h, oci8dp.h, ocidfn.h, odci.h, oro.h, nzerror.h, occiData.h, ociap.h, ociextp.h, oratypes.h, ort.h, nzt.h, occi.h, ociapr.h, oci.h, orid.h, occiAQ.h, occiObjects.h, ocidef.h, ocikpr.h, ori.h, xa.h

And the libraries:
oci.lib, ociw32.lib, oraocci10.lib for Windows

And: libclntsh.so, libocci.so for Linux.

Get the headers and libraries:

You can get the headers and libraries files from www.oracle.com, looking for Oracle C++ Call Interface (OCCI)

WINDOWS:

VC:
-Download the package instantclient-sdk for Windows from www.oracle.com
The package contains the directories include/ and lib/
Copy the headers and libraries to the VC include/ and lib/

Mingw:
-You need the Mingw32 utilities reimp.exe (in package mingw-utils-x.x.x)
And dlltool.exe in package (binutils-x.x.x-mingw32-bin)
If you are working with Mingw, maybe you already have these files
If you don have it, you can download from:
http://www.mingw.org/ or http://sourceforge.net/projects/mingw/

-Create the .def files from oci.lib, ociw32.lib and oraocci10.lib
reimp -d oci.lib
reimp -d ociw32.lib
reimp -d oraocci10.lib

-Create the gcc .a libraries from the .def files
dlltool -k --input-def oci.def --dllname oci.dll --output-lib liboci.a
dlltool -k --input-def ociw32.def --dllname ociw32.dll --output-lib libociw32.a
dlltool -k --input-def oraocci10.def --dllname oraocci10.dll --output-lib liboraocci10.a

-Copy the instantclient-sdk headers to your gcc include directory and the .a files to your gcc lib directory

-Compile with the linker option -loci

LINUX:

-Download and install the rpms instantclient-basic and instantclient-sdk from www.oracle.com

-The directory instantclient_x_x/sdk/include/ contains the .h headers files
-Copy this files to /usr/include/

-Edit the file demo.mk in the directory instantclient_x_x/sdk/demo/
-Find the "section buildoci" and coment the lines:
# $(REMOVE) $(ICLIBHOME)libclntsh$(SO_EXT)
# $(REMOVE) $(ICLIBHOME)libocci$(SO_EXT)
-Make the .so files
make -f demo.mk buildoci EXE=cdemo81 OBJS=cdemo81.o

-Copy the libraries libclntsh.so and libocci.so to /usr/lib/

-You can remove the file instantclient-sdk and the file instantclient-basic
if you won't use this last one

-Compile with the linker option -locci -lclntsh

The Oracle Instant Client version used for this samples is 10.2.0.4

If you don't have a Oracle Client installed, you can use the Oracle Instant Client

Configuring my Oracle Instant Client environment:

WINDOWS:

-Add this lines to the autoexec.bat:

PATH=%PATH%;C:\OracleIC
SET TNS_ADMIN=C:\OracleIC
SET LD_LIBRARY_PATH=C:\OracleIC
SET NLS_LANG=SPANISH_MEXICO.UTF8

-"C:\OracleIC" is the path where you copy the Oracle Instant Client

LINUX:

-Add this lines to your profile (ejm: .bashrc, .bash_profile)

PATH=/usr/lib/oracle/x.x.x/client:$PATH
export TNS_ADMIN=/etc/oracle
export LD_LIBRARY_PATH=/usr/lib/oracle/x.x.x/client:$LD_LIBRARY_PATH
export NLS_LANG=MEXICAN SPANISH_MEXICO.WE8MSWIN1252

-"/usr/lib/oracle/x.x.x/client" is the directory of the Oracle Instant Client libraries

-Copy your tnsnames.ora to the TNS_ADMIN directory

-Change the appropiate NLS_LANG for your Oracle DB

-At runtime, only need the instantclient-basic package

NOTE: Only the library libwxOra requires the oracle include and link options, the application no longer needs them.

I have all the files for VC and Eclipse projects with a sample of use ready for download at SourceForge

Load the library using wx/dynload.h and include the wxOraLib.h file in your app
and include the file wxOraDef.h to your app to let it know the methods of wxOraLib.

The source code:

//---------------------------------------------------------------------------

//

// Name: wxOra.cpp

// Author: eduardo canedo

// Created: 28/05/2007 10:30:00 a.m.

// Description: Exported functions from wxOraLib

//

//---------------------------------------------------------------------------

#include <wx/dynlib.h>

#include "wxOraLib.h"



WXDLL_ENTRY_FUNCTION();



extern "C" WXEXPORT wxOra* oraIni(wxString strTit, wxString strSid, wxString strUsr, wxString strPas)

{

return new wxOra(strTit, strSid, strUsr, strPas);

}



extern "C" WXEXPORT void oraFin(wxOra* oraObj)

{

oraObj->~wxOra();

}



extern "C" WXEXPORT bool oraExe(wxOra* oraObj, wxString strQry)

{

return oraObj->ExecQry(strQry);

}



extern "C" WXEXPORT bool oraSel(wxOra* oraObj, wxString strQry, std::vector< std::vector<wxString> > *aryDat=NULL, wxGridTableBase *grdDat=NULL)

{

return oraObj->SelcQry(strQry, aryDat, grdDat);

}



extern "C" WXEXPORT bool oraArcW(wxOra* oraObj, wxString strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

return oraObj->EscArc(strArc, strLob, strTbl, strCmp, numCnd);

}



extern "C" WXEXPORT bool oraObjW(wxOra* oraObj, wxChar *strArc, size_t size, wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

return oraObj->EscLob(strArc, size, strLob, strTbl, strCmp, numCnd);

}



extern "C" WXEXPORT bool oraArcR(wxOra* oraObj, wxString strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

return oraObj->LeeArc(strArc, strLob, strTbl, strCmp, numCnd);

}



extern "C" WXEXPORT int oraObjR(wxOra* oraObj, wxChar *strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

return oraObj->LeeLob(strArc, strLob, strTbl, strCmp, numCnd);

}




//---------------------------------------------------------------------------

//

// Name: wxOraDef.h

// Author: eduardo canedo

// Created: 28/05/2007 10:30:00 a.m.

// Description: Function headers for wxOraLib

//

//---------------------------------------------------------------------------

typedef wxOra* (*oraIni)(wxString, wxString, wxString, wxString);

typedef void* (*oraFin)(wxOra*);

typedef bool* (*oraExe)(wxOra*, wxString);

typedef bool* (*oraSel)(wxOra*, wxString, std::vector< std::vector<wxString> >*, wxGridTableBase*);

typedef int (*oraArcW)(wxOra*, wxString, wxString, wxString, wxString, int);

typedef bool* (*oraObjW)(wxOra*, wxChar*, size_t, wxString, wxString, wxString, int);

typedef int (*oraArcR)(wxOra*, wxString, wxString, wxString, wxString, int);

typedef int (*oraObjR)(wxOra*, wxChar*, wxString, wxString, wxString, int);




//---------------------------------------------------------------------------

//

// Name: wxOraLib.h

// Author: eduardo canedo

// Created: 28/05/2007 10:30:00 a.m.

// Description: wxOra class declaration

//

//---------------------------------------------------------------------------



#ifdef __BORLANDC__

#pragma hdrstop

#endif



#ifndef WX_PRECOMP

#include <wx/wx.h>

#include <wx/dialog.h>

#else

#include <wx/wxprec.h>

#endif



#include <wx/grid.h>

#include <wx/file.h>

#include <vector>

#include <oci.h>



#define MAXLOBLEN 512000 //MAX SIZE FOR LOB'S



class wxOra

{

private:

void ClsLobHnd();

bool ChkErr(OCIError *errhp, sword status);

bool SelLob(wxString strLob, wxString strTbl, wxString strCmp, int numCnd);



public:

wxOra(wxString strTit, wxString strSid, wxString strUsr, wxString strPas);

~wxOra();



bool bolCon;

bool ExecQry(wxString strQry);

bool SelcQry(wxString strQry, std::vector< std::vector<wxString> > *aryDat=NULL, wxGridTableBase *grdDat=NULL);

bool LeeArc(wxString strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd);

int LeeLob(wxChar *strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd);

bool EscArc(wxString strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd);

bool EscLob(wxChar *strArc, size_t size, wxString strLob, wxString strTbl, wxString strCmp, int numCnd);

};




//---------------------------------------------------------------------------

//

// Name: wxOraLib.cpp

// Author: eduardo canedo

// Created: 28/05/2007 10:30:00 a.m.

// Description: wxOra class implementation

//

//---------------------------------------------------------------------------



#include "wxOraLib.h"



static OCISession *authp = (OCISession *) 0;

static OCIDefine *deflob = (OCIDefine *) 0;

static OCILobLocator *blob;

static OCIServer *srvhp;

static OCISvcCtx *svchp;

static OCIError *errhp;

static OCIStmt *stmQry;

static wxString msgTit;

static OCIEnv *envhp;

static sword status;

static text *qry;



wxOra::wxOra(wxString strTit, wxString strSid, wxString strUsr, wxString strPas)

{

bolCon = true;

msgTit = strTit;

text *sid = (text*) strSid.c_str();

text *usr = (text*) strUsr.c_str();

text *pas = (text*) strPas.c_str();



//ENVIRONMENT CREATOR

sword errcode = 0;

wxString strErr;

errcode = OCIEnvCreate((OCIEnv **) &envhp, (ub4) OCI_DEFAULT, (dvoid *) 0, (dvoid * (*)(dvoid *,size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t)) 0, (void (*)(dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **) 0);



if (errcode != 0)

{

strErr.Printf("ERROR en creación de ambiente ORACLE: %d", errcode);

wxMessageBox(strErr, msgTit, wxOK | wxICON_ERROR);

bolCon = false;

}



//START DATABASE CONECTION

(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0);



(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0);



(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0);



if (!ChkErr(errhp, OCIServerAttach( srvhp, errhp, sid, strlen((char*)sid), 0)))

bolCon = false;



if (!ChkErr(errhp, OCIAttrSet( (dvoid *) svchp, OCI_HTYPE_SVCCTX, (dvoid *)srvhp, (ub4) 0, OCI_ATTR_SERVER, (OCIError *) errhp)))

bolCon = false;



if (!ChkErr(errhp, OCIHandleAlloc((dvoid *) envhp, (dvoid **)&authp, (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0)))

bolCon = false;



if (!ChkErr(errhp, OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) usr, (ub4) strlen((char *)usr), (ub4) OCI_ATTR_USERNAME, errhp)))

bolCon = false;



if (!ChkErr(errhp, OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) pas, (ub4) strlen((char *)pas), (ub4) OCI_ATTR_PASSWORD, errhp)))

bolCon = false;



if (!ChkErr(errhp, OCISessionBegin ( svchp, errhp, authp, OCI_CRED_RDBMS, (ub4) OCI_DEFAULT)))

bolCon = false;



(void) OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *) authp, (ub4) 0, (ub4) OCI_ATTR_SESSION, errhp);

}



wxOra::~wxOra()

{

ChkErr(errhp, OCISessionEnd(svchp, errhp, authp, OCI_DEFAULT));

ChkErr(errhp, OCIServerDetach(srvhp, errhp, OCI_DEFAULT));

if (authp) (void) OCIHandleFree(authp, OCI_HTYPE_SESSION);

if (srvhp) (void) OCIHandleFree(srvhp, OCI_HTYPE_SERVER);

if (svchp) (void) OCIHandleFree(svchp, OCI_HTYPE_SVCCTX);

if (errhp) (void) OCIHandleFree(errhp, OCI_HTYPE_ERROR);

if (envhp) (void) OCIHandleFree(envhp, OCI_HTYPE_ENV);

}


//EXECUTE QUERY

bool wxOra::ExecQry(wxString strQry)

{

qry = (text*) strQry.c_str();

if (!ChkErr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmQry, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)))

return false;

if (!ChkErr(errhp, OCIStmtPrepare(stmQry, errhp, qry, (ub4) strlen((char *) qry), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)))

return false;

status = OCIStmtExecute(svchp, stmQry, errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT);

if (!ChkErr(errhp, status))

return false;

status = OCITransCommit(svchp, errhp, 0);

if (!ChkErr(errhp, status))

return false;

if (stmQry) (void) OCIHandleFree(stmQry, OCI_HTYPE_STMT);



return true;

}


//SELECT QUERY INTO AN ARRAY OR INTO AN WXGRID

bool wxOra::SelcQry(wxString strQry, std::vector< std::vector<wxString> > *aryDat, wxGridTableBase *grdDat)

{

if (aryDat==NULL && grdDat==NULL)

{

wxMessageBox(wxT("ERROR A data container is required"), msgTit, wxOK | wxICON_ERROR);

return false;

}

else if (aryDat!=NULL && grdDat!=NULL)

{

wxMessageBox(wxT("ERROR Only one data container is required"), msgTit, wxOK | wxICON_ERROR);

return false;

}



ub4 rows = 1;

ub2 type = 0;

ub2 dcml = 0;

ub4 numcols = 0;

wxString strTmp;

qry = (text*) strQry.c_str();

OCIParam *colhd = (OCIParam *) 0;



if (!ChkErr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmQry, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)))

return false;

if (!ChkErr(errhp, OCIStmtPrepare(stmQry, errhp, (OraText *)qry, (ub4)strlen((char *)qry), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)))

return false;

if (!ChkErr(errhp, OCIStmtExecute(svchp, stmQry, errhp, 0, 0, (OCISnapshot *) 0, (OCISnapshot *) 0, OCI_DESCRIBE_ONLY)))

return false;

if (!ChkErr(errhp, OCIAttrGet((dvoid *)stmQry, OCI_HTYPE_STMT, (dvoid *)&numcols, (ub4 *)0, OCI_ATTR_PARAM_COUNT, errhp)))

return false;



for (int i=1;i<=(int)numcols;i++)

{

type = 0;

dcml = 0;

if (!ChkErr(errhp, OCIParamGet((dvoid *)stmQry, OCI_HTYPE_STMT, errhp, (dvoid **)&colhd, i)))

return false;

if (!ChkErr(errhp, OCIAttrGet((dvoid *)colhd, OCI_DTYPE_PARAM, (dvoid *)&type, (ub4 *)0, OCI_ATTR_DATA_TYPE, errhp)))

return false;

if (!ChkErr(errhp, OCIAttrGet((dvoid *)colhd, OCI_DTYPE_PARAM, (dvoid *)&dcml, (ub4 *)0, OCI_ATTR_SCALE, errhp)))

return false;



switch(type)

{

case SQLT_NUM: /* NUMBER */

break;

case SQLT_INT: /* INTEGER */

break;

case SQLT_UIN: /* UINT */

break;

case SQLT_FLT: /* FLOAT */

break;

case SQLT_CHR: /* VARCHAR2 */

break;

case SQLT_VCS: /* VARCHAR */

break;

case SQLT_AFC: /* CHAR */

break;

case SQLT_AVC: /* CHARZ */

break;

case SQLT_LNG: /* LONG */

break;

case SQLT_LVC: /* LONG */

break;

case SQLT_STR: /* STRING */

break;

case SQLT_DAT: /* DATE */

break;

default:

if (stmQry) (void) OCIHandleFree(stmQry, OCI_HTYPE_STMT);

wxMessageBox(wxT("ERROR Data type not supported"), msgTit, wxOK | wxICON_ERROR);

return false;

}

}



ub4 bufLen = 1182; //SUPPORTS FIELDS UP TO 1100 CHARS



//char* bufFld[numcols-1]; //VC BUG, FIXED

char** bufFld=(char**)malloc((numcols-1) * (sizeof(char) * bufLen));



OCIDefine* define = 0;



if (grdDat!=NULL)

{

grdDat->DeleteCols(0, grdDat->GetNumberCols());

grdDat->DeleteRows(0, grdDat->GetNumberRows());

grdDat->AppendCols(numcols);

}

else

{

aryDat->clear();

}



for (int i=1;i<=(int)numcols;i++)

{

bufFld[i-1] = (char*)malloc(sizeof(char) * bufLen);

if (!ChkErr(errhp, OCIDefineByPos(stmQry, &define, errhp, (ub4)i, bufFld[i-1], bufLen + 1, (ub2)SQLT_STR, 0, 0, 0, OCI_DEFAULT)))

return false;

}



status = OCIStmtExecute(svchp, stmQry, errhp, rows, 0, (OCISnapshot *) 0, (OCISnapshot *) 0, OCI_DEFAULT);

if(status == OCI_NO_DATA)

{

if (stmQry) (void) OCIHandleFree(stmQry, OCI_HTYPE_STMT);

wxMessageBox(wxT("NO se encontraron registros"), msgTit, wxOK | wxICON_INFORMATION);

return false;

}



if (grdDat!=NULL)

{

grdDat->AppendRows(1);

for (int i=0;i<(int)numcols;i++)

{

strTmp.Printf("%s", bufFld[i]);

grdDat->SetValue(0, i, strTmp);

}

}

else

{

std::vector<wxString> aryTmp;

for (int i=0;i<(int)numcols;i++)

{

strTmp.Printf("%s", bufFld[i]);

aryTmp.push_back(strTmp);

}

aryDat->push_back(aryTmp);

}



while(true)

{

status = OCIStmtFetch(stmQry, errhp, rows, OCI_FETCH_NEXT, OCI_DEFAULT);

if(status == OCI_NO_DATA) break;



if (grdDat!=NULL)

{

grdDat->AppendRows(1);

for (int i=0;i<(int)numcols;i++)

{

strTmp.Printf("%s", bufFld[i]);

grdDat->SetValue(grdDat->GetNumberRows()-1, i, strTmp);

}

}

else

{

std::vector<wxString> aryTmp;

for (int i=0;i<(int)numcols;i++)

{

strTmp.Printf("%s", bufFld[i]);

aryTmp.push_back(strTmp);

}

aryDat->push_back(aryTmp);

}

}



for (int i=1;i<=(int)numcols;i++)

memset((void *)bufFld[i-1], '\0', (size_t)bufLen);



if (stmQry) (void) OCIHandleFree(stmQry, OCI_HTYPE_STMT);

return true;

}


//BLOBS FUNTION SUPPORT
bool wxOra::SelLob(wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

wxString strQry = wxT("SELECT "+strLob+" FROM "+strTbl+" WHERE "+strCmp+"=:1 FOR UPDATE");

qry = (text*) strQry.c_str();



if (!ChkErr(errhp, OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmQry, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0)))

return false;

if (!ChkErr(errhp, OCIDescriptorAlloc((dvoid *) envhp, (dvoid **) &blob, (ub4)OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0)))

return false;

if (!ChkErr(errhp, OCIStmtPrepare(stmQry, errhp, qry, (ub4) strlen((char *) qry), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)))

return false;

OCIBind *bndhp = 0;

if (!ChkErr(errhp, OCIBindByPos(stmQry, &bndhp, errhp, (ub4) 1, (dvoid *) &numCnd, (sb4) sizeof(numCnd), SQLT_INT, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DEFAULT)))

return false;

if (OCIDefineByPos(stmQry, &deflob, errhp, (ub4) 1, (dvoid *) &blob, sizeof(OCILobLocator*), (ub2) SQLT_BLOB, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) OCI_DEFAULT))

return false;

status = OCIStmtExecute(svchp, stmQry, errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot*) 0, (OCISnapshot*) 0, (ub4) OCI_DEFAULT);

if (!ChkErr(errhp, status))

return false;



return true;

}


//WRITE FILE INTO THE DB

bool wxOra::EscArc(wxString strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

wxFile file(strArc);

if (file.IsOpened())

{

long iSize = (long)file.Length();

//wxChar strBuf[iSize];//VC BUG, FIXED

wxChar* strBuf=(wxChar*) malloc(sizeof(wxChar) * iSize);



if (iSize < 1)

{

wxMessageBox(wxT("ERROR In file size"), msgTit, wxOK | wxICON_ERROR);

return false;

}

else if (iSize > MAXLOBLEN)

{

wxMessageBox(wxT("ERROR The file size is biger than expected"), msgTit, wxOK | wxICON_ERROR);

return false;

}

else

{

memset(strBuf, 0, (size_t)iSize);

size_t iRead = file.Read(strBuf, (size_t)iSize);

if (iRead < (size_t)iSize)

{

wxMessageBox(wxT("ERROR Betwen content and file size"), msgTit, wxOK | wxICON_ERROR);

memset((void *)strBuf, '\0', (size_t)iSize);

return false;

}

else if (!EscLob(strBuf, iRead, strLob, strTbl, strCmp, numCnd))

{

memset((void *)strBuf, '\0', (size_t)iSize);

return false;

}

}

file.Close();

}

else

{

wxMessageBox(wxT("ERROR Can't Open file"), msgTit, wxOK | wxICON_ERROR);

return false;

}

return true;

}


//WRITE BLOB INTO THE DB

bool wxOra::EscLob(wxChar *strArc, size_t size, wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

wxString strQry;

strQry.Printf("UPDATE %s SET %s=EMPTY_BLOB() WHERE %s=%d", strTbl.c_str(), strLob.c_str(), strCmp.c_str(), numCnd);

if (!ExecQry(strQry))

return false;



if (!SelLob(strLob, strTbl, strCmp, numCnd))

return false;



ub4 arcLen = (ub4)size;

if (!ChkErr(errhp, OCILobWrite(svchp, errhp, blob, &arcLen, (ub4) 1, (dvoid *)strArc, arcLen, OCI_ONE_PIECE, (dvoid *)0, (OCICallbackLobWrite) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT)))

{

ClsLobHnd();

wxMessageBox(wxT("ERROR Can't load the file"), msgTit, wxOK | wxICON_ERROR);

return false;

}

status = OCITransCommit(svchp, errhp, 0);

if (!ChkErr(errhp, status))

{

ClsLobHnd();

return false;

}

ClsLobHnd();

return true;

}


//READ FILE FROM DB

bool wxOra::LeeArc(wxString strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

int numLen;

wxChar strBuf[MAXLOBLEN];

numLen = LeeLob(strBuf, strLob, strTbl, strCmp, numCnd);

if (numLen > 0)

{

wxFile file;

if (!file.Open(strArc, wxFile::write))

{

wxMessageBox(wxT("ERROR Can't Open file"), msgTit, wxOK | wxICON_ERROR);

memset((void *)strBuf, '\0', (size_t) numLen);

return false;

}

file.Write(strBuf, (size_t) numLen);

file.Close();

}

else

{

wxMessageBox(wxT("ERROR Can't read file"), msgTit, wxOK | wxICON_ERROR);

memset((void *)strBuf, '\0', (size_t) numLen);

return false;

}

return true;

}


//READ BLOB FROM DB

int wxOra::LeeLob(wxChar *strArc, wxString strLob, wxString strTbl, wxString strCmp, int numCnd)

{

if (!SelLob(strLob, strTbl, strCmp, numCnd))

return 0;



ub4 lobSze = 0;

if (!ChkErr(errhp, OCILobGetLength(svchp, errhp, blob, &lobSze)))

{

ClsLobHnd();

wxMessageBox(wxT("ERROR In file size"), msgTit, wxOK | wxICON_ERROR);

return 0;

}



if (!ChkErr(errhp, OCILobRead(svchp, errhp, blob, &lobSze, 1, (dvoid *) strArc,

(ub4) MAXLOBLEN, (dvoid *)0,

(OCICallbackLobRead) 0,

(ub2) 0, (ub1) SQLCS_IMPLICIT)))

{

ClsLobHnd();

wxMessageBox(wxT("ERROR Can't Read file"), msgTit, wxOK | wxICON_ERROR);

return 0;

}



ClsLobHnd();

return (int) lobSze;

}



void wxOra::ClsLobHnd()

{

if (stmQry) (void) OCIHandleFree(stmQry, OCI_HTYPE_STMT);

if (blob) (void) OCIHandleFree(blob, OCI_DTYPE_LOB);

}


//OPTIMIZED ERROR MANAGER FOR wxOraLib

bool wxOra::ChkErr(OCIError *errhp, sword status)

{

text errbuf[512];

sb4 errcode = 0;

wxString strErr;

bool bolRes = true;



switch (status)

{

case OCI_SUCCESS:

bolRes = true;

break;

case OCI_SUCCESS_WITH_INFO:

wxMessageBox(wxT("OCI_SUCCESS_WITH_INFO"), msgTit, wxOK | wxICON_INFORMATION);

bolRes = false;

break;

case OCI_NEED_DATA:

wxMessageBox(wxT("OCI_NEED_DATA"), msgTit, wxOK | wxICON_INFORMATION);

bolRes = false;

break;

case OCI_CONTINUE:

wxMessageBox(wxT("OCI_CONTINUE"), msgTit, wxOK | wxICON_INFORMATION);

bolRes = false;

break;

case OCI_NO_DATA:

wxMessageBox(wxT("ERROR OCI_NODATA"), msgTit, wxOK | wxICON_ERROR);

bolRes = false;

break;

case OCI_ERROR:

(void) OCIErrorGet((dvoid *)errhp, (ub4) 1, (text *) NULL, &errcode,

errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);

strErr.Printf("ERROR %.*s", 512, errbuf);

wxMessageBox(strErr, msgTit, wxOK | wxICON_ERROR);

bolRes = false;

break;

case OCI_INVALID_HANDLE:

wxMessageBox(wxT("ERROR OCI_INVALID_HANDLE"), msgTit, wxOK | wxICON_ERROR);

bolRes = false;

break;

case OCI_STILL_EXECUTING:

wxMessageBox(wxT("ERROR OCI_STILL_EXECUTE"), msgTit, wxOK | wxICON_ERROR);

bolRes = false;

break;

default:

wxMessageBox(wxT("UNEXPECTED ERROR"), msgTit, wxOK | wxICON_ERROR);

bolRes = false;

break;

}

return bolRes;

}

No comments:

Post a Comment