// BDE - (C) Copyright 1995 by Borland International // Blobio.c #include "snipit.h" static const char szTblName[] = "blob_io"; static const char szTblType[] = szDBASE; static DBIResult InsertRec(hDBICur hCur, UINT16 uID); static DBIResult FillBlobInfo(hDBICur hCur, pBYTE pRecBuf); static BOOL FillString(pBYTE pString); static SNIPFAR FLDDesc fldDesc[] = { { 1, // Field number "Item_ID", // Field name fldINT16, // Field type 0, // Field subtype 1, // Field size ( 1 or 0 // except BLOB or string ) 0, // Decimal places ( 0 ) - // computed 0, // Offset in record ( 0 ) 0, // Length in bytes ( 0 ) 0, // For Null bits ( 0 ) fldvNOCHECKS, // Validity checks ( 0 ) fldrREADWRITE // Rights }, { 2, "BigText", fldBLOB, fldstMEMO, 0, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE } }; // Array of field descriptors static const unsigned uNumFields = sizeof(fldDesc) / sizeof(fldDesc[0]); //===================================================================== // Function: // BlobIO(void); // // Description: // This example will show how to modify and insert a BLOB field // that is greater than 64K. //===================================================================== void BlobIO (void) { DBIResult rslt; // Return value from IDAPI functions hDBIDb hDb; // database handle hDBICur hCur; // Cursor handle CRTblDesc crTblDsc; // Table descriptor BOOL bOverWrite = TRUE; // Overwrite, yes/no flag Screen("*** Using BLOB's ***\r\n"); BREAK_IN_DEBUGGER(); Screen(" Initializing IDAPI..."); if (InitAndConnect(&hDb) != DBIERR_NONE) { Screen("\r\n*** End of Example ***"); return; } Screen(" Setting the database directory..."); rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory); ChkRslt(rslt, "SetDirectory"); // Initialize the table create descriptor. memset(&crTblDsc, 0, sizeof(CRTblDesc)); strcpy(crTblDsc.szTblName, szTblName); strcpy(crTblDsc.szTblType, szTblType); crTblDsc.iFldCount = uNumFields; crTblDsc.pfldDesc = fldDesc; Screen(" Creating the %s %s table...", szTblName, szTblType); rslt = DbiCreateTable(hDb, bOverWrite, &crTblDsc); if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Open the %s table...", szTblName); rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType, NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } // Insert the records. Screen("\r\n Inserting the first record..."); InsertRec(hCur, 1); Screen("\r\n Inserting the second record..."); InsertRec(hCur, 5); Screen("\r\n Close the %s table...", szTblName); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); // Delete the table and its related files from disk. Screen(" Delete the %s table...", szTblName); rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); Screen("\r\n Close the database and exit IDAPI..."); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); } //===================================================================== // Function: // InsertRec(hCur, iID); // // Input: hCur - Cursor to the table // iID - ID for the field // // Return: Result of adding the record to the table. // // Desc: This function will add a record to the given table. //===================================================================== DBIResult InsertRec (hDBICur hCur, UINT16 iID) { DBIResult rslt; // Value returned from IDAPI functions CURProps tblProps; // Table properties pBYTE pRecBuf; // Record buffer Screen(" Acquire the table's properties..."); rslt = DbiGetCursorProps(hCur, &tblProps); ChkRslt(rslt, "GetCursorProps"); // Allocate memory for the record buffer. pRecBuf = (pBYTE) malloc(tblProps.iRecBufSize * sizeof(BYTE)); if (pRecBuf == NULL) { Screen(" Error - Out of memory"); return DBIERR_NOMEMORY; } Screen(" Initialize record buffer..."); rslt = DbiInitRecord(hCur, pRecBuf); ChkRslt(rslt, "InitRec"); Screen(" Put the ID number into the record buffer..."); rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) &iID); ChkRslt(rslt, "PutField"); // Fill the BLOB information pointer with 64K or more of text. FillBlobInfo(hCur, pRecBuf); Screen(" Insert the record into the table..."); rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf); ChkRslt(rslt, "InsertRecord"); Screen(" Free the BLOB..."); rslt = DbiFreeBlob(hCur, pRecBuf, 2); ChkRslt(rslt, "FreeBlob"); // Free the record buffer. free(pRecBuf); return rslt; } //===================================================================== // Function: // FillBlobInfo(hCur, pRecBuf); // // Input: hCur - Cursor to the table // pRecBuf - Record buffer // // Return: Result of filling the BLOB field // // Desc: This function will fill the BLOB field of the given // record buffer with a predefined string. //===================================================================== DBIResult FillBlobInfo (hDBICur hCur, pBYTE pRecBuf) { pBYTE Temp1 = NULL; pBYTE Temp2 = NULL; pBYTE Temp3 = NULL; pBYTE Temp4 = NULL; UINT16 Len = 30000; long lWritePos = 0; DBIResult rslt; // Allocate memory for the four temporary buffers that will // total more than 64K of memory. Temp1 = (pBYTE) malloc((sizeof(BYTE) * Len) + 1); Temp2 = (pBYTE) malloc((sizeof(BYTE) * Len) + 1); Temp3 = (pBYTE) malloc((sizeof(BYTE) * Len) + 1); Temp4 = (pBYTE) malloc((sizeof(BYTE) * Len) + 1); if ((Temp1 == NULL) || (Temp2 == NULL) || (Temp3 == NULL) || (Temp4 == NULL)) { if (Temp1) free(Temp1); if (Temp2) free(Temp2); if (Temp3) free(Temp3); if (Temp4) free(Temp4); return DBIERR_NOMEMORY; } Screen(" Filling the temporary strings with data..."); FillString(Temp1); FillString(Temp2); FillString(Temp3); FillString(Temp4); Screen(" Open the BLOB for writing..."); rslt = DbiOpenBlob(hCur, pRecBuf, 2, dbiREADWRITE); ChkRslt(rslt, "OpenBlob"); Screen(" Put the first part of the BLOB into the BLOB field..."); rslt = DbiPutBlob(hCur, pRecBuf, 2, 0, strlen((pCHAR) Temp1), Temp1); ChkRslt(rslt, "PutBlob1"); // Set lWritePos to point to the position inside the BLOB. lWritePos = (long)strlen((pCHAR) Temp1); Screen(" Put the second part of the BLOB into the BLOB field..."); rslt = DbiPutBlob(hCur, pRecBuf, 2, lWritePos, strlen((pCHAR) Temp2), Temp2); ChkRslt(rslt, "PutBlob2"); // Increment lWritePos to point to the position inside the BLOB. lWritePos = lWritePos + (long)strlen((pCHAR) Temp2); Screen(" Put the third part of the BLOB into the BLOB field..."); rslt = DbiPutBlob(hCur, pRecBuf, 2, lWritePos, strlen((pCHAR) Temp3), Temp3); ChkRslt(rslt, "PutBlob3"); // Increment lWritePos to point to the position inside the BLOB. lWritePos = lWritePos + (long)strlen((pCHAR) Temp3); Screen(" Put the final part of the BLOB into the BLOB field..."); rslt = DbiPutBlob(hCur, pRecBuf, 2, lWritePos, strlen((pCHAR) Temp4), Temp4); ChkRslt(rslt, "PutBlob4"); // Free all the buffers. free(Temp1); free(Temp2); free(Temp3); free(Temp4); return DBIERR_NONE; } //===================================================================== // Function: // FillString(pString); // // Input: pString - String that will hold the random letters // // Return: TRUE - String has been filled // // Desc: This function will fill the string with a predefined // string. //===================================================================== BOOL FillString (pBYTE pString) { CHAR Filler[] = "This is a test"; UINT16 uNum = 1900; // Number of times to copy the string UINT16 uLen; // Length of the filler string UINT16 i; // Loop counter pCHAR pszTemp; // Temporary pointer used in strcpy. // First copy the filler into the buffer. pszTemp = strcpy((pCHAR)pString, Filler); uLen = strlen((pCHAR)pString); // Now fill the rest of the string. for (i = 1; i < uNum; i++) { pszTemp = pszTemp + uLen; pszTemp = strcpy((pCHAR)pszTemp, Filler); } return TRUE; }