Purpose: Fetches a single row of data into the supplied object.
| Return Type | Function name | Arguments |
|---|---|---|
| hzEcode | hdbBinRepos::Fetch | (hzChain&,uint32_t,) |
Declared in file: hzDatabase.h
Defined in file : hdbBinRepos.cpp
Function Logic:
Function body:
hzEcode hdbBinRepos::Fetch (hzChain& datum)uint32_t datumId,
{
// Purpose: Fetches a single row of data into the supplied object.
//
// Arguments: 1) obj The object to be populated
// 2) datumId The object id
//
// Returns: E_NOTOPEN If the reader stream is not open for reading
// E_READFAIL The reader stream is already in a fialed state
// E_CORRUPT Row metadata not as expected. Possible overwrites
// E_FORMAT Data format error
// E_OK The operation was successful
_hzfunc("hdbBinRepos::Fetch") ;
_datum_hd hdr ; // Datum header
char* workBuf ; // Working buffer
uint64_t nAddr ; // Addr of object in file
uint64_t nPosn ; // Posn of m_Reader
uint32_t toGet ; // Bytes to get in the next read operation
uint32_t soFar ; // Bytes read so far
hzEcode rc = E_OK ; // Return code
// if (datum.Copies() > 1)
// threadLog("Copies of chain %u\n", datum.Copies()) ;
datum.Clear() ;
// Repos not initialized?
if (m_nInitState < 1)
return E_NOINIT ;
// Repos not open?
if (m_nInitState < 2)
return E_NOTOPEN ;
// Zero datum id?
if (!datumId)
return hzerr(E_RANGE, "NULL datum id") ;
// Datum id out of range
if (datumId > m_nSeqId)
{
threadLog("Out of range\n") ;
rc = E_RANGE ;
}
// Read in requested object
m_LockIrd.Lock() ;
// Get datum header
nAddr = (datumId-1)* sizeof(_datum_hd) ;
m_RdI.seekg((streamoff) nAddr) ;
nPosn = m_RdI.tellg() ;
if (nPosn != nAddr)
{
rc = E_READFAIL ;
threadLog("Could not seek header address %u for datum %u\n", nAddr, datumId) ;
}
else
{
threadLog("Found header address %u for datum %u\n", nAddr, datumId) ;
m_RdI.read((char*) &hdr, sizeof(_datum_hd)) ;
if (m_RdI.fail())
{
rc = E_READFAIL ;
threadLog("Could not read header for datum %u", datumId) ;
m_RdI.clear() ;
}
}
m_LockIrd.Unlock() ;
if (rc != E_OK)
return rc ;
workBuf = new char[HZ_BLOCKSIZE] ;
m_LockDrd.Lock() ;
// Get datum
threadLog("Found datum for datum %u addr %u, size %u\n", datumId, hdr.m_Addr, hdr.m_Size) ;
m_RdD.seekg((streamoff) hdr.m_Addr) ;
nPosn = m_RdD.tellg() ;
if (nPosn != hdr.m_Addr)
{
rc = E_READFAIL ;
threadLog("Could not seek data address %ul for datum %d\n", hdr.m_Addr, datumId) ;
}
else
{
// threadLog("case A hdr size %u\n", hdr.m_Size) ;
toGet = HZ_BLOCKSIZE - (hdr.m_Addr % HZ_BLOCKSIZE) ;
if (toGet > hdr.m_Size)
toGet = hdr.m_Size ;
soFar = 0;
// threadLog("case B toget %u\n", toGet) ;
m_RdD.read(workBuf, toGet) ;
if (m_RdD.gcount() != toGet)
threadLog("Warning: toget %u, got %u\n", toGet, m_RdD.gcount()) ;
datum.Append(workBuf, toGet) ;
soFar += toGet ;
for (; soFar < hdr.m_Size ;)
{
toGet = hdr.m_Size - soFar ;
if (toGet > HZ_BLOCKSIZE)
toGet = HZ_BLOCKSIZE ;
// threadLog("case C sofar %u toget %u\n", soFar, toGet) ;
m_RdD.read(workBuf, toGet) ;
if (m_RdD.gcount() != toGet)
threadLog("Warning: toget %u, got %u\n", toGet, m_RdD.gcount()) ;
datum.Append(workBuf, toGet) ;
soFar += toGet ;
}
// threadLog("case 5\n") ;
if (m_RdD.fail())
{
rc = E_READFAIL ;
threadLog("m_RdD failed\n") ;
m_RdD.clear() ;
}
threadLog("Now have %u bytes in Datum\n", datum.Size()) ;
}
m_LockDrd.Unlock() ;
delete [] workBuf ;
return rc ;
}