20 unsigned int idx = arrayIndex;
26int32_t
DB2Row::getInt(
const std::string& field,
unsigned int arrayIndex)
const
29 unsigned int idx = arrayIndex;
36 if (fi->
type ==
"int8")
39 std::memcpy(&v, &raw,
sizeof(int8_t));
40 return static_cast<int32_t
>(v);
42 if (fi->
type ==
"int16")
45 std::memcpy(&v, &raw,
sizeof(int16_t));
46 return static_cast<int32_t
>(v);
50 std::memcpy(&v, &raw,
sizeof(int32_t));
57 unsigned int idx = arrayIndex;
63 std::memcpy(&result, &raw,
sizeof(
float));
70 unsigned int idx = arrayIndex;
78static std::string
toLower(
const std::string& s)
80 std::string result = s;
81 std::transform(result.begin(), result.end(), result.begin(),
82 [](
unsigned char c) { return static_cast<char>(std::tolower(c)); });
89 : m_reader(std::move(reader)), m_fields(std::move(fields))
91 for (
size_t i = 0; i <
m_fields.size(); i++)
99 auto it =
m_reader->m_idToRecordIndex.find(
id);
100 if (it !=
m_reader->m_idToRecordIndex.end())
101 return DB2Row(
this, it->second);
107 if (index < m_reader->m_recordLocations.size())
108 return DB2Row(
this, index);
114 return m_reader->m_recordLocations.size();
127 const std::string lower =
toLower(name);
135 size_t numStart = lower.size();
136 while (numStart > 0 && std::isdigit(
static_cast<unsigned char>(lower[numStart - 1])))
139 if (numStart > 0 && numStart < lower.size())
141 std::string baseName = lower.substr(0, numStart);
145 int idx = std::stoi(lower.substr(numStart)) - 1;
146 if (idx >= 0 &&
static_cast<unsigned int>(idx) <
m_fields[it->second].arraySize)
148 arrayIndex =
static_cast<unsigned int>(idx);
154 LOG_ERROR <<
"DB2Table: field not found: " << name;
160 return m_reader->m_recordLocations[recordIndex].recordID;
165 const auto& loc =
m_reader->m_recordLocations[recordIndex];
166 const auto& sec =
m_reader->m_sections[loc.sectionIndex];
173 auto relIt = sec.relationshipMap.find(loc.localIndex);
174 return (relIt != sec.relationshipMap.end()) ? relIt->second : 0;
177 unsigned int result = 0;
178 m_reader->readFieldValue(loc.sectionIndex, loc.localIndex,
180 loc.recordID, result);
186 const auto& loc =
m_reader->m_recordLocations[recordIndex];
187 const auto& sec =
m_reader->m_sections[loc.sectionIndex];
188 const unsigned char* recordOffset =
m_reader->getRecordOffset(loc.sectionIndex, loc.localIndex);
191 unsigned int val = 0;
193 m_reader->readFieldValue(loc.sectionIndex, loc.localIndex,
197 const char* stringPtr =
nullptr;
202 const unsigned char* ptr = recordOffset;
203 for (
int f = 0; f <= field.
pos &&
static_cast<size_t>(f) <
m_fields.size(); f++)
213 std::string v(
reinterpret_cast<const char*
>(ptr));
217 stringPtr =
reinterpret_cast<const char*
>(ptr);
219 else if (
m_reader->m_wdcVersion > 2)
222 const uint32_t dataPos =
m_reader->m_fieldStorageInfo[field.
pos].field_offset_bits / 8;
224 uint32_t outsideDataSize = 0;
225 for (uint32_t s = 0; s < loc.sectionIndex; s++)
226 outsideDataSize +=
m_reader->m_sections[s].recordDataSize;
228 const int32_t absoluteRecordOfs =
229 static_cast<int32_t
>(loc.localIndex *
m_reader->m_header.record_size) -
230 static_cast<int32_t
>(
m_reader->m_header.record_count *
m_reader->m_header.record_size);
232 const int32_t stringTableIndex =
233 static_cast<int32_t
>(outsideDataSize) + absoluteRecordOfs +
234 static_cast<int32_t
>(dataPos) +
static_cast<int32_t
>(val);
236 const unsigned char* strBase =
nullptr;
237 for (uint32_t s = 0; s <
m_reader->m_sections.size(); s++)
239 const auto& strSec =
m_reader->m_sections[s];
240 const int32_t localOfs = stringTableIndex -
static_cast<int32_t
>(strSec.previousStringTableSize);
241 if (localOfs >= 0 &&
static_cast<uint32_t
>(localOfs) < strSec.stringTableSize)
243 strBase =
m_reader->m_fileData + strSec.stringTableOffset + localOfs;
249 stringPtr =
reinterpret_cast<const char*
>(strBase);
256 stringPtr =
reinterpret_cast<const char*
>(
257 recordOffset +
m_reader->m_fieldStorageInfo[field.
pos].field_offset_bits / 8 + val -
258 ((
m_reader->m_header.record_count - sec.recordCount) *
m_reader->m_header.record_size));
261 std::string result(stringPtr ? stringPtr :
"");
262 std::replace(result.begin(), result.end(),
'"',
'\'');
static std::string toLower(const std::string &s)
Lightweight handle to a single row in a DB2Table.
std::string getString(const std::string &field, unsigned int arrayIndex=0) const
float getFloat(const std::string &field, unsigned int arrayIndex=0) const
int32_t getInt(const std::string &field, unsigned int arrayIndex=0) const
uint32_t recordID() const
uint32_t getUInt(const std::string &field, unsigned int arrayIndex=0) const
DB2Row getRow(uint32_t id) const
const DB2FieldInfo * findField(const std::string &name) const
uint32_t readUInt(size_t recordIndex, const DB2FieldInfo &field, unsigned int arrayIndex) const
std::vector< DB2FieldInfo > m_fields
DB2Table(std::unique_ptr< DB2Reader > reader, std::vector< DB2FieldInfo > fields)
size_t getRowCount() const
DB2Row getRowByIndex(size_t index) const
std::unordered_map< std::string, size_t > m_fieldNameToIndex
std::string readString(size_t recordIndex, const DB2FieldInfo &field, unsigned int arrayIndex) const
std::unique_ptr< DB2Reader > m_reader
const DB2FieldInfo * resolveField(const std::string &name, unsigned int &arrayIndex) const
uint32_t getRecordID(size_t recordIndex) const
Describes a single field (column) in a DB2 table.
bool isRelationshipData
Whether this field is relationship data.
int pos
DB2 field position index (-1 for non-inline/key).
std::string type
Type string ("text", "float", "int8", "uint8", etc.).
unsigned int arraySize
Array size (> 1 for array fields).
bool isKey
Whether this field is the primary key.