Files
TeslaRel410/BORLAND/BDE/EXAMPLES/SNIPIT/STORPROC.C
T
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
  is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
  Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
  (extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
  BT game source (never mixed into CODE/). Round 1-3 state:
  * 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
    (BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
    since 1996.
  * BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
    its binary-recorded line 400 exactly.
  * BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
    (Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
    TeamScore=12 flagged [T4]).
  * MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
    (VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
    the period compiler is the drift detector).
  * Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
    (per-TU verification sweep under authentic OPT.MAK flags).
  * README: corrected roadmap - MECH.HPP is the capstone grown with the mech
    TU reconstructions; BTREG.CPP green = the header-family milestone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 07:33:26 -05:00

547 lines
19 KiB
C++

// BDE - (C) Copyright 1995 by Borland International
// storproc.c
#include "snipit.h"
static pCHAR szTblName = "STORPROC";
// Field Descriptor used in creating a table.
static SNIPFAR FLDDesc fldDesc[] =
{
{ // Field 1 - FRSTNAME
1, // Field Number
"FRSTNAME", // Field Name
fldZSTRING, // Field Type
fldUNKNOWN, // Field Subtype
12, // Field Size ( 1 or 0, except
// BLOb or CHAR field )
0, // Decimal places ( 0 )
// computed
0, // Offset in record ( 0 )
0, // Length in Bytes ( 0 )
0, // For Null Bits ( 0 )
fldvNOCHECKS, // Validiy checks ( 0 )
fldrREADWRITE // Rights
},
{ // Field 2 - LASTNAME
2, "LASTNAME", fldZSTRING, fldUNKNOWN,
12, 0, 0, 0, 0,
fldvNOCHECKS, fldrREADWRITE
}
};
// Index Descriptor - describes the index associated with the table.
static IDXDesc IdxDesc =
{
{ "PROCIDX" }, // Name
1, // Number
{ NULL }, // Tag name (dBASE only)
{ NULL }, // Optional format
FALSE, // Primary?
TRUE, // Unique?
FALSE, // Descending?
TRUE, // Maintained?
FALSE, // SubSet?
FALSE, // Expression index?
NULL, // for QBE only
2, // Fields in key
NULL, // Length in bytes
FALSE, // Index out of date?
0, // Key Type of Expression
{ 2, 1 }, // Array of field numbers
{ NULL }, // Key expression
{ NULL }, // Key Condition
FALSE, // Case insensitive
0, // Block size in bytes
0 // Restructure number
};
// Function prototypes
static DBIResult CreateSQLTable(hDBIDb hDb, pCHAR pszTblName);
static DBIResult AddRecord(hDBICur hCur, pCHAR pFirst, pCHAR pLast);
static DBIResult CreateProcedure(hDBIDb hDb);
static const UINT16 uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
//=====================================================================
// Function:
// StoredProcedures();
//
// Description:
// This file shows how to create, use, and get information on
// stored procedures. Note that the syntax for stored procedure
// creation is specific to a given server.
//=====================================================================
void
StoredProcedures (void)
{
hDBIDb hDb; // Handle to the database.
DBIResult rslt; // Return value from IDAPI functions.
BOOL bProcs; // Supports stored procedures?
hDBICur hCur; // Cursor Handle.
SPParamDesc spParamDesc; // Used to determine size of record Buffer,
// and number of paramaters.
pSPParamDesc pspParamDesc; // Holds info on all parameters.
pBYTE pRecBuf; // Record buffer.
UINT16 iCount; // Current Parameter
UINT16 iRecBufSize; // Size of the record
DBINAME szProcName; // Name of the procedure
hDBIStmt hStmt; // Statement handle
UINT16 uLength; // Length of the property
int i; // Loop counter
CHAR szDelete[] = "DROP PROCEDURE PROCTEST";
// Statement to delete the procedure
Screen("*** Stored Procedure Example ***\r\n");
BREAK_IN_DEBUGGER();
Screen(" Initializing IDAPI...");
if (InitAndConnect2(&hDb) != DBIERR_NONE)
{
Screen("\r\n*** End of Example ***");
return;
}
rslt = DbiGetProp(hDb, dbPROCEDURES, &bProcs, sizeof(bProcs),
&uLength);
ChkRslt(rslt, "GetProp");
if (!bProcs)
{
Screen("\r\n Error - specified server does not support stored"
" procedures.");
Screen(" Close the database and exit IDAPI...");
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
return;
}
rslt = CreateSQLTable(hDb, szTblName);
if (rslt)
{
Screen(" Close the database and exit IDAPI...");
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
return;
}
rslt = DbiSetProp(hDb, dbPARAMFMTQMARK, TRUE);
ChkRslt(rslt, "SetProp");
rslt = CreateProcedure(hDb);
if (rslt)
{
Screen("\r\n Drop the procedure...");
rslt = DbiQExecDirect(hDb, qrylangSQL, szDelete, NULL);
ChkRslt(rslt, "QExecDirect");
Screen(" Delete the table...");
rslt = DbiDeleteTable(hDb, szTblName, NULL);
ChkRslt(rslt, "DeleteTable");
Screen(" Close the database and exit IDAPI...");
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
return;
}
Screen(" Display the list of procedures...");
rslt = DbiOpenSPList(hDb, FALSE, TRUE, NULL, &hCur);
ChkRslt(rslt, "OpenSPList");
if (hCur)
{
DisplayInMemoryTable(hCur, 0);
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "CloseCursor");
}
strcpy(szProcName, "PROCTEST");
Screen("\r\n Display information about the parameters to"
" the procedure...");
rslt = DbiOpenSPParamList(hDb, szProcName, FALSE, 0, &hCur);
ChkRslt(rslt, "OpenSPParamList");
if (hCur)
{
DisplayInMemoryTable(hCur, 0);
rslt = DbiSetToEnd(hCur);
ChkRslt(rslt, "SetToEnd");
// Get the last property to determine the count of properties...
rslt = DbiGetPriorRecord(hCur, dbiNOLOCK, (pBYTE)&spParamDesc, NULL);
ChkRslt(rslt, "GetPriorRecord");
pspParamDesc = (pSPParamDesc)malloc((spParamDesc.uParamNum + 1) *
sizeof(SPParamDesc));
memset((pVOID)pspParamDesc, 0, spParamDesc.uParamNum *
sizeof(SPParamDesc));
rslt = DbiSetToBegin(hCur);
ChkRslt(rslt, "SetToBegin");
// Get descriptors for each field
iRecBufSize = 0;
iCount = 0;
while ((rslt = DbiGetNextRecord(hCur, dbiNOLOCK,
(pBYTE)&(pspParamDesc[iCount]), NULL))
== DBIERR_NONE)
{
// Oracle CHAR parameters are unsized...
if (pspParamDesc[iCount].uFldType == fldZSTRING)
{
if (pspParamDesc[iCount].iUnits1 == 0)
{
pspParamDesc[iCount].iUnits1 = 12;
}
pspParamDesc[iCount].uLen = pspParamDesc[iCount].iUnits1 + 1;
}
if (pspParamDesc[iCount].uFldType == fldBOOL)
{
pspParamDesc[iCount].uLen = 2;
}
if (pspParamDesc[iCount].uFldType == fldINT32)
{
pspParamDesc[iCount].uLen = 4;
}
iRecBufSize = iRecBufSize + pspParamDesc[iCount].uLen;
pspParamDesc[iCount].szName[0] = 0;
if (iCount)
{
pspParamDesc[iCount].uOffset = pspParamDesc[iCount - 1].uOffset
+
pspParamDesc[iCount - 1].uLen;
}
iCount++;
}
if (rslt != DBIERR_EOF)
{
Screen("\r\n");
ChkRslt(rslt, "GetNextRecord");
}
// Allocate space for the record buffer and parameters
pRecBuf = (pBYTE)malloc(iRecBufSize * sizeof(CHAR));
if (!pRecBuf)
{
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "CloseCursor");
Screen("\r\n Drop the procedure...");
rslt = DbiQExecDirect(hDb, qrylangSQL, szDelete, NULL);
ChkRslt(rslt, "QExecDirect");
rslt = DbiDeleteTable(hDb, szTblName, NULL);
ChkRslt(rslt, "DeleteTable");
Screen(" Error - Out of memory");
CloseDbAndExit(&hDb);
return;
}
memset((pVOID)pRecBuf, 0, iRecBufSize);
// Set the input parameter - this is done for Sybase, as
// in/out information is not returned for parameters to
// stored procedures on Sybase.
i = 0;
while ((i < iCount) && ((pspParamDesc[i].eParamType != paramIN)
&& (pspParamDesc[i].eParamType != paramINOUT)
&& (pspParamDesc[i].eParamType != paramUNKNOWN)))
{
i++;
}
if (pspParamDesc[i].eParamType == paramUNKNOWN)
{
pspParamDesc[i].eParamType = paramIN;
}
if (i < iCount)
{
memcpy((pVOID)(pRecBuf + pspParamDesc[i].uOffset), "Wong", 4);
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "CloseCursor");
Screen("\r\n Execute the procedure...");
// Could also use DbiQExecProcDirect:
// rslt = DbiQExecProcDirect(hDb, szProcName, iCount, pspParamDesc,
// pRecBuf, &hCur);
rslt = DbiQPrepareProc(hDb, szProcName, iCount, pspParamDesc, NULL,
&hStmt);
ChkRslt(rslt, "QPrepareProc");
rslt = DbiQSetProcParams(hStmt, iCount, pspParamDesc, pRecBuf);
ChkRslt(rslt, "QSetProcParams");
// For InterBase only:
// Can also use the following syntax to get the results
// of a procedure in the forum of a cursor:
//
// 'select * from <procedure_name>;
rslt = DbiQExec(hStmt, &hCur);
ChkRslt(rslt, "QExec");
if (hCur)
{
Screen("\r\n Return Values:");
DisplayTable(hCur, 0);
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "CloseCursor");
}
else if (rslt == DBIERR_NONE)
{
Screen("\r\n Return Values:\r\n");
Screen(" First Name: %s",
&(pRecBuf[pspParamDesc[1].uOffset]));
Screen(" Last Name: %s",
&(pRecBuf[pspParamDesc[2].uOffset]));
}
rslt = DbiQFree(&hStmt);
ChkRslt(rslt, "QFree");
}
else
{
Screen("\r\n Error - no input parameter...");
}
}
if (pRecBuf)
{
free(pRecBuf);
}
if (pspParamDesc)
{
free(pspParamDesc);
}
Screen("\r\n Drop the procedure...");
rslt = DbiQExecDirect(hDb, qrylangSQL, szDelete, NULL);
ChkRslt(rslt, "QExecDirect");
rslt = DbiDeleteTable(hDb, szTblName, NULL);
ChkRslt(rslt, "DeleteTable");
Screen(" Close the database and exit IDAPI...");
CloseDbAndExit(&hDb);
Screen("\r\n*** End of Example ***");
}
//=====================================================================
// Function:
// CreateSQLTable(hDb, pszTblName);
//
// Input: phDb - Pointer to the database handle.
// pszTblName - The name of the table to create.
//
// Return: Result returned by IDAPI.
//
// Description:
// This function will create a table and add records to that
// table.
//=====================================================================
DBIResult
CreateSQLTable (hDBIDb hDb, pCHAR pszTblName)
{
DBIResult rslt; // Value returned from IDAPI functions
CRTblDesc crTblDesc; // Table Descriptor
hDBICur hCur; // Cursor used for adding records
// Initialize the Table Create Descriptor.
memset(&crTblDesc, 0, sizeof(CRTblDesc));
strcpy(crTblDesc.szTblName, pszTblName);
crTblDesc.iFldCount = uNumFields;
crTblDesc.pfldDesc = fldDesc;
crTblDesc.iIdxCount = 1;
crTblDesc.pidxDesc = &IdxDesc;
Screen(" Creating the table...");
rslt = DbiCreateTable(hDb, TRUE, &crTblDesc);
if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
{
return rslt;
}
rslt = DbiOpenTable(hDb, pszTblName, NULL,
NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
xltFIELD, FALSE, NULL, &hCur);
if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
{
rslt = DbiDeleteTable(hDb, pszTblName, NULL);
ChkRslt(rslt, "DeleteTable");
return rslt;
}
// Add records to the table.
Screen(" Adding records to the table...");
rslt = AddRecord(hCur, "Tom", "Smith");
rslt = AddRecord(hCur, "Jim", "Jones");
rslt = AddRecord(hCur, "Larry", "Peterson");
rslt = AddRecord(hCur, "Jane", "Jackson");
rslt = AddRecord(hCur, "Mary", "Wong");
rslt = DbiCloseCursor(&hCur);
ChkRslt(rslt, "ClostTable");
return rslt;
}
//=====================================================================
// Function:
// AddRecord (hDBICur hCur, pCHAR pFirst, pCHAR pLast)
//
// Input: hCur - The table handle
// pFirst - First Name
// pLast - Last Name
//
// Return: Result of adding the record to the table
//
// Description:
// Insert a record into the table.
//=====================================================================
DBIResult
AddRecord (hDBICur hCur, pCHAR pFirst, pCHAR pLast)
{
DBIResult rslt; // Return value from IDAPI functions
pBYTE pRecBuf; // Record buffer
CURProps TblProps; // Table properties
// Allocate a record buffer.
rslt = DbiGetCursorProps(hCur, &TblProps);
ChkRslt(rslt, "GetCursorProps");
pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
if (pRecBuf == NULL)
{
Screen(" Error - Out of memory");
return DBIERR_NOMEMORY;
}
// Clear the record buffer, then add the data.
rslt = DbiInitRecord(hCur, pRecBuf);
ChkRslt(rslt, "InitRecord");
rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) pFirst);
ChkRslt(rslt, "PutField");
rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE) pLast);
ChkRslt(rslt, "PutField");
rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf);
ChkRslt(rslt, "InsertRecord");
free(pRecBuf);
return rslt;
}
//=====================================================================
// Function:
// CreateProcedure (hDBIDb hDb)
//
// Input: hDb - Handle to the Database
//
// Return: Result of creating the procedure
//
// Description:
// This function is used to create a stored procedure on a
// given server. As each server has it's own specific syntax
// for creating stored procedures, this function determines
// the type of the server and uses the appropriate syntax.
//=====================================================================
DBIResult
CreateProcedure (hDBIDb hDb)
{
DBIResult rslt = DBIERR_NONE; // Return value from BDE
DBINAME szDbType; // Type of the server
UINT16 uLength; // Length of the property
pCHAR szCreate = NULL; // SQL Statment to pass to
// DbiQExecDirect
CHAR szCreateIB[] = // Syntax for InterBase
"CREATE PROCEDURE PROCTEST (LAST VARCHAR(12))\r\n"
"RETURNS (FIRSTNAME VARCHAR(10),\r\n"
" LASTNAME VARCHAR(12))\r\n"
"AS\r\n"
"BEGIN\r\n"
" FOR select * from STORPROC s\r\n"
" where s.LASTNAME = :LAST\r\n"
" INTO :FIRSTNAME, :LASTNAME\r\n"
" DO\r\n"
" SUSPEND;\r\n"
"END;\r\n";
CHAR szCreateOra [] = // Syntax for Oracle
"CREATE PROCEDURE PROCTEST (LNAME IN VARCHAR,\r\n"
" FRST OUT VARCHAR,\r\n"
" LST OUT VARCHAR)\r\n"
"AS BEGIN\r\n"
" select FRSTNAME, LASTNAME into FRST, LST from STORPROC\r\n"
" where LASTNAME = LNAME;\r\n"
"END PROCTEST;\r\n";
CHAR szCreateSyb [] = // Syntax for Sybase
"CREATE PROCEDURE PROCTEST @LNAME varchar(12)\r\n"
"as\r\n"
" select s.FRSTNAME, s.LASTNAME from STORPROC s\r\n"
" where s.LASTNAME = @LNAME\r\n";
rslt = DbiGetProp(hDb, dbDATABASETYPE, &szDbType, DBIMAXNAMELEN,
&uLength);
ChkRslt(rslt, "GetProp");
if (!strcmp(szDbType, "INTRBASE"))
{
szCreate = szCreateIB;
}
else
{
if (!strcmp(szDbType, "ORACLE"))
{
szCreate = szCreateOra;
}
else
{
if (!strcmp(szDbType, "SYBASE"))
{
szCreate = szCreateSyb;
}
}
}
if (szCreate)
{
Screen("\r\n Create the procedure with the following query:"
"\r\n\r\n%s...", szCreate);
rslt = DbiQExecDirect(hDb, qrylangSQL, szCreate, NULL);
ChkRslt(rslt, "QExecDirect");
}
else
{
Screen(" Error - server not supported.");
// Force an error
rslt = 1;
}
return rslt;
}