#ifdef RCSID static char *RCSid = "$Header: cdemolb.c 03-jan-97.15:16:51 echen Exp $ "; #endif /* RCSID */ /* Copyright (c) Oracle Corporation 1996, 1997, 1998. All Rights Reserved. */ /* NAME cdemolb.c - C Demo program to illustrate the OCI Lob interface. DESCRIPTION This C file contains code to demonstrate the use of the OCI LOB (Large OBject) interface. It provides a typical example of how OCI programs can be used to create/insert lob data, and then access and manipulate (read, write,copy, append, trim) the data. PUBLIC FUNCTION(S) PRIVATE FUNCTION(S) RETURNS EX_SUCCESS - if the program terminates succesfully. EX_FAILURE - if it encounters any error. NOTES In the beta-1 release only Lob reads and writes (OCILobRead() , OCILobWrite()) with no callbacks have been demonstrated. More examples will be added in future releases. Before executing this program execute the following sql program: cdemolb.sql Executing this sql program will delete any earlier tables created by this demo and create new tables. Each time the demo program runs successfully it adds row to tables. So it might be a good idea to run the sql program after several runs of the demo program. MODIFIED (MM/DD/YY) svedala 02/17/98 - OCI obsoletion changes cchau 03/03/97 - change functions to long names azhao 01/31/97 - removed isnull azhao 01/30/97 - fix lint error echen 01/03/97 - OCI beautification pshah 10/11/96 - kosinski 09/24/96 - Merge Win32 changes into base development aroy 07/22/96 - Demonstrate the OCI Lob interface. aroy 07/22/96 - Creation */ /*---------------------------------------------------------------------*/ #include #include #include #include int main () { ldemodef *ctx; sword retval = 0; ub2 i; OCILobLocator *lobp; /* allocate and initialise ctx structure */ ctx = alloc_handles(); /* allocate lob descriptor */ alloc_lob_desc(ctx, &lobp); /* Allocate statement/bind/define handles */ alloc_stmt_handles (ctx, ctx->s1, 0, 0); /* for the insert statement */ alloc_stmt_handles (ctx, ctx->s2, 0, 2); /* Selecting lob descriptor */ /* Authenticate the user (connect to server) */ authenticate_user(ctx); /* Insert/Select Lob locator */ insert_select_loc(ctx, lobp); /* Write Data into Lob Locator */ Write_to_loc(ctx, lobp); /* Read data from Lob Locator */ Read_from_loc(ctx, lobp); /* free lob locator */ (void) OCIDescriptorFree((dvoid *) lobp, (ub4) OCI_DTYPE_LOB); /* Deauthenticate (logout) user */ deauthenticate(ctx); /* Clean up */ cleanup(ctx); return(EX_SUCCESS); } /* --------------------------------------------------------------------- */ /* Write data into the selected lob locator */ void Write_to_loc(ctx, lobp) ldemodef *ctx; OCILobLocator *lobp; { FILE *fp; ub1 buf[BUFSIZE+1]; ub4 offset; ub4 amtp; ub4 lenp; sb4 err; if ((fp = fopen (CDEMOLB_TEXT_FILE, "r"))==NULL) { COMMENT ("Cannot open file for reading"); exit (EX_FAILURE); } offset = 1; /* Offset for Lobs start at 1 */ while (!feof(fp)) { /* Read the data from file */ memset (buf, '\0', BUFSIZE); fread(buf, BUFSIZE, 1, fp); buf[BUFSIZE]='\0'; /* printf("%s",buf); */ /*Write it into the locator */ amtp = BUFSIZE; /* IN/OUT : IN - amount if data to write */ err = OCILobWrite (ctx->svchp, ctx->errhp, lobp, &amtp, offset, (dvoid *) buf, (ub4) BUFSIZE, OCI_ONE_PIECE, (dvoid *)0, (sb4 (*)()) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT); if (err == OCI_SUCCESS) { printf("Written some data...\n"); offset += amtp; } else { fclose(fp); errrpt (ctx, (text *) "Write_to_loc : OCILobWrite"); } } COMMENT("Write Successful"); /* Length of the Lob */ err = OCILobGetLength(ctx->svchp, ctx->errhp, lobp, &lenp); if (err != OCI_SUCCESS) printf (" get lob length fails. err = %d\n\n", err); else printf (" Written %d bytes into Locator Successfully.\n\n", lenp); fclose (fp); } /* --------------------------------------------------------------------- */ /* Read data from the lob locator */ void Read_from_loc(ctx, lobp) ldemodef *ctx; OCILobLocator *lobp; { ub1 buf[BUFSIZE+1]; ub4 offset; ub4 amtp; ub4 lenp=0; sb4 err; COMMENT("Read from the locator."); /* Length of the Lob */ if (OCILobGetLength(ctx->svchp, ctx->errhp, lobp, &lenp) != OCI_SUCCESS) errrpt(ctx, "Read_from_loc: OCILobGetLength"); else { printf(" Length of Locator is %d\n", lenp); } printf ("Enter the offset to read from (starting at 1): "); scanf("%d", &offset); printf ("Enter amount to read: "); scanf("%d", &amtp); if ((offset + amtp - 1) > lenp) { printf ("Error: Trying to get more data than available!\n"); exit (EX_FAILURE); } printf("\n------------------------------------------------------------------\n"); /* Read the locator */ do { memset ((dvoid *)buf, '\0', BUFSIZE); err = OCILobRead(ctx->svchp, ctx->errhp, lobp, &amtp, offset, (dvoid *) buf, (ub4)BUFSIZE , (dvoid *) 0, (sb4 (*)()) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT); if (err == OCI_SUCCESS || err == OCI_NEED_DATA) { buf[BUFSIZE] = '\0'; printf ("%s", buf); offset +=amtp; } else errrpt(ctx, "Read_from_loc : OCILobRead"); } while (err == OCI_NEED_DATA); printf("\n------------------------------------------------------------------\n"); printf("\n"); } /* --------------------------------------------------------------------- */ /* insert one row into table and select the lob descriptor. */ static void alloc_stmt_handles (ctx, sptr, nbnd, ndfn) ldemodef *ctx; stmtdef *sptr; sb2 nbnd; sb2 ndfn; { sb2 i; /* Get statement handles */ if (OCIHandleAlloc( (dvoid *)(ctx->envhp), (dvoid **) &(sptr->stmhp), (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0) != OCI_SUCCESS ) { COMMENT("Fail to OCIHandleAlloc for statement handle"); cleanup(ctx); exit(EX_FAILURE); } /* Get bind handles */ /* for (i=0; istmhp), (dvoid **) &(sptr->bndhp[i]), (ub4) OCI_HTYPE_BIND, (size_t) 0, (dvoid **) 0) != OCI_SUCCESS ) { COMMENT("Fail to OCIHandleAlloc for bind handle"); cleanup(ctx); exit(EX_FAILURE); } } */ /* Get define handles */ /* for (i=0; istmhp), (dvoid **) &(sptr->dfnhp[i]), (ub4) OCI_HTYPE_DEFINE, (size_t) 0, (dvoid **) 0) != OCI_SUCCESS ) { COMMENT("Fail to OCIHandleAlloc for define handle"); cleanup(ctx); exit(EX_FAILURE); } } */ } /* --------------------------------------------------------------------- */ /* insert one row into table and select the lob descriptor. */ static void insert_select_loc(ctx, lobsrc) ldemodef *ctx; dvoid *lobsrc; { /* Insert an empty locator */ if (OCIStmtPrepare (ctx->s1->stmhp, ctx->errhp, insstmt[0], strlen ((const char *)insstmt[0])+1, OCI_NTV_SYNTAX, OCI_DEFAULT) != OCI_SUCCESS) errrpt (ctx, "insert_select_loc: OCIStmtPrepare"); if (OCIStmtExecute (ctx->svchp, ctx->s1->stmhp, ctx->errhp, 1, 0, 0, 0, OCI_DEFAULT)) errrpt (ctx, "insert_select_loc: OCIStmtExecute") ; printf("Inserted...\n"); /* Now select the locator */ if (OCIStmtPrepare (ctx->s2->stmhp, ctx->errhp, selstmt[0], strlen ((const char *)selstmt[0])+1, OCI_NTV_SYNTAX, OCI_DEFAULT)) errrpt (ctx, "insert_select_loc: OCIStmtPrepare"); /* Call define for each column of interest */ if (OCIDefineByPos (ctx->s2->stmhp, &(ctx->s2->dfnhp[1]), ctx->errhp, 1, (dvoid *)&lobsrc, 0 , SQLT_CLOB, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT)) errrpt (ctx, "insert_select_loc: ocidefn"); printf("About to select locator...\n"); if (OCIStmtExecute (ctx->svchp, ctx->s2->stmhp, ctx->errhp, 1, 0, 0, 0, OCI_DEFAULT)) errrpt (ctx, "insert_select_loc: OCIStmtExecute") ; } /*-------------------------------------------------------------------------*/ /* Authenticate users and connect to server */ static void authenticate_user(ctx) ldemodef *ctx; { COMMENT ("Authentication for scott is progress..."); if (OCIServerAttach(ctx->srvhp, ctx->errhp, "", 0, 0) != OCI_SUCCESS ) errrpt(ctx, "conn2serv - OCIServerAttach"); /* Set the server handle in service handle */ if (OCIAttrSet (ctx->svchp, OCI_HTYPE_SVCCTX, ctx->srvhp, 0, OCI_ATTR_SERVER, ctx->errhp) != OCI_SUCCESS) errrpt(ctx, "conn2serv - OCIAttrSet"); /* set the username/password in user handle */ if (OCIAttrSet(ctx->authp, OCI_HTYPE_SESSION, "scott", 5, OCI_ATTR_USERNAME, ctx->errhp) != OCI_SUCCESS) errrpt(ctx, "conn2serv - OCIAttrSet"); if (OCIAttrSet(ctx->authp, OCI_HTYPE_SESSION, "tiger", 5, OCI_ATTR_PASSWORD, ctx->errhp) != OCI_SUCCESS) errrpt(ctx, "conn2serv - OCIAttrSet"); /* Authenticate */ if (OCISessionBegin (ctx->svchp, ctx->errhp, ctx->authp, OCI_CRED_RDBMS, OCI_DEFAULT) != OCI_SUCCESS) errrpt(ctx, "conn2serv - ocisauth"); COMMENT ("Authentication for scott successful."); /* Set the Authentication handle in the service handle */ if (OCIAttrSet(ctx->svchp, OCI_HTYPE_SVCCTX, ctx->authp, 0, OCI_ATTR_SESSION, ctx->errhp) != OCI_SUCCESS) errrpt(ctx, "conn2serv - OCIAttrSet"); } /*-------------------------------------------------------------------------*/ /* create all tables. */ static void deauthenticate(ctx) ldemodef *ctx; { COMMENT ("Logging off...\n"); if (OCISessionEnd(ctx->svchp, ctx->errhp, ctx->authp, (ub4) 0)) { errrpt(ctx, (CONST text *)"logout: ologof"); } COMMENT("Logged off.\n"); } /*---------------------------------------------------------------*/ /* ** Allocate and initialise global and local context structures. */ static ldemodef *alloc_handles() { ldemodef * csptr; int i; csptr = (ldemodef *) malloc(sizeof(ldemodef)); if (csptr == (ldemodef *) 0) { COMMENT("Unable To Allocate Memory for ldemodef ..."); exit(EX_FAILURE); } memset ((void *) csptr, '\0', sizeof(ldemodef)); if (OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0, (dvoid * (*)()) 0, (dvoid * (*)())0, (void (*)()) 0 ) != OCI_SUCCESS) { COMMENT("Fail to OCIInitialize..."); /* cleanup(csptr); */ exit(EX_FAILURE); } if (OCIEnvInit( (OCIEnv **) &csptr->envhp, (ub4) OCI_DEFAULT, (size_t) 0, (dvoid **) 0 ) != OCI_SUCCESS) { COMMENT("Fail to OCIEnvInit for service handle..."); cleanup(csptr); exit(EX_FAILURE); } /* Get Error Handle */ if (OCIHandleAlloc( (dvoid *) csptr->envhp, (dvoid **) &csptr->errhp, (ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0) != OCI_SUCCESS) { COMMENT("Fail to OCIHandleAlloc for error handle..."); cleanup(csptr); exit(EX_FAILURE); } /* server context */ if (OCIHandleAlloc( (dvoid *) csptr->envhp, (dvoid **) &csptr->srvhp, (ub4) OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0) != OCI_SUCCESS) { COMMENT("Fail to OCIHandleAlloc for server handle..."); cleanup(csptr); exit(EX_FAILURE); } /* Service Context */ if (OCIHandleAlloc( (dvoid *) csptr->envhp, (dvoid **) &csptr->svchp, (ub4) OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0) != OCI_SUCCESS ) { COMMENT("Fail to OCIHandleAlloc for service handle..."); cleanup(csptr); exit(EX_FAILURE); } /* Auth Context */ if (OCIHandleAlloc( (dvoid *) csptr->envhp, (dvoid **) &csptr->authp, (ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0) != OCI_SUCCESS ) { COMMENT("Fail to OCIHandleAlloc for user handle..."); cleanup(csptr); exit(EX_FAILURE); } /*Stmtdef structures */ csptr->s1 = (stmtdef *) malloc(sizeof(stmtdef)); if (csptr->s1 == (stmtdef *) 0) { COMMENT("Unable To Allocate Memory for stmtdef ..."); exit(EX_FAILURE); } memset ((void *) csptr->s1, '\0', sizeof(stmtdef)); csptr->s2 = (stmtdef *) malloc(sizeof(stmtdef)); if (csptr->s2 == (stmtdef *) 0) { COMMENT("Unable To Allocate Memory for stmtdef ..."); exit(EX_FAILURE); } memset ((void *) csptr->s2, '\0', sizeof(stmtdef)); return (csptr); } /* -------------------------------------------------------------- */ /* Allocate lob descriptors. */ static void alloc_lob_desc(ctx, lobsrc) ldemodef *ctx; OCILobLocator **lobsrc; { if (OCIDescriptorAlloc((dvoid *) ctx->envhp, (dvoid **) lobsrc, (ub4) OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0) != OCI_SUCCESS ) { errrpt(ctx, (CONST text *) "OCIDescriptorAlloc"); cleanup(ctx); exit(EX_FAILURE); } } /* -------------------------------------------------------------- */ /* Clean up all structures used. */ static void cleanup(ctx) ldemodef *ctx; { (void) OCIHandleFree((dvoid *) ctx->srvhp, (ub4) OCI_HTYPE_SERVER); (void) OCIHandleFree((dvoid *) ctx->svchp, (ub4) OCI_HTYPE_SVCCTX); (void) OCIHandleFree((dvoid *) ctx->errhp, (ub4) OCI_HTYPE_ERROR); (void) OCIHandleFree((dvoid *) ctx->authp, (ub4) OCI_HTYPE_SESSION); (void) OCIHandleFree((dvoid *) ctx->s1, (ub4) OCI_HTYPE_STMT); (void) OCIHandleFree((dvoid *) ctx->s2, (ub4) OCI_HTYPE_STMT); } /* ------------------------------------------------------------------------- */ /* ** Format the output error message and obtain error string from Oracle ** given the error code */ void errrpt(ctx, op) ldemodef *ctx; CONST text *op; { text msgbuf[LONGTEXTLENGTH]; sb4 errcode = 0; fprintf(stdout,"ORACLE error during %s\n", op); OCIErrorGet ((dvoid *) ctx->errhp, (ub4) 1, (text *) NULL, &errcode, msgbuf, (ub4) sizeof(msgbuf), (ub4) OCI_HTYPE_ERROR); fprintf(stdout,"ERROR CODE = %d\n", errcode); fprintf(stdout,"%s\n", msgbuf); exit(EX_FAILURE); } /* end of file cdemolb.c */