Skip to content

Commit afecb52

Browse files
committed
Expose descriptor metadata: name, relation, alias, owner, charSetId, subType
Add six new fields to the Descriptor struct, populated from IMessageMetadata during statement preparation. This resolves the 'FIXME: more things' placeholder and provides ODBC-level metadata without requiring consumers to use the low-level Firebird API. Fields use the naming requested by the maintainer: - 'name' (from getField) instead of 'field' - 'charSetId' (from getCharSet) instead of 'charSet' Closes #37
1 parent 8be6ce5 commit afecb52

3 files changed

Lines changed: 98 additions & 1 deletion

File tree

src/fb-cpp/Descriptor.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define FBCPP_DESCRIPTOR_H
2727

2828
#include "fb-api.h"
29+
#include <string>
2930

3031

3132
///
@@ -279,7 +280,36 @@ namespace fbcpp
279280
/// Indicates whether the column or parameter can contain null values.
280281
///
281282
bool isNullable;
282-
// FIXME: more things
283+
284+
///
285+
/// Column or parameter name.
286+
///
287+
std::string name;
288+
289+
///
290+
/// Table or relation this column belongs to (empty for expressions).
291+
///
292+
std::string relation;
293+
294+
///
295+
/// Column alias as it appears in the query's SELECT list.
296+
///
297+
std::string alias;
298+
299+
///
300+
/// Owner of the relation (empty for expressions).
301+
///
302+
std::string owner;
303+
304+
///
305+
/// Character set ID for string and BLOB columns.
306+
///
307+
unsigned charSetId;
308+
309+
///
310+
/// Sub-type (BLOB sub-type or numeric sub-type).
311+
///
312+
int subType;
283313
};
284314
} // namespace fbcpp
285315

src/fb-cpp/Statement.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ Statement::Statement(
108108
.offset = 0,
109109
.nullOffset = 0,
110110
.isNullable = static_cast<bool>(metadata->isNullable(&statusWrapper, index)),
111+
.name = metadata->getField(&statusWrapper, index),
112+
.relation = metadata->getRelation(&statusWrapper, index),
113+
.alias = metadata->getAlias(&statusWrapper, index),
114+
.owner = metadata->getOwner(&statusWrapper, index),
115+
.charSetId = metadata->getCharSet(&statusWrapper, index),
116+
.subType = metadata->getSubType(&statusWrapper, index),
111117
};
112118

113119
switch (descriptor.originalType)

src/test/Statement.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,67 @@ BOOST_AUTO_TEST_CASE(constructorProvidesMetadataHandles)
187187
BOOST_CHECK(outputDescriptor.adjustedType == DescriptorAdjustedType::STRING);
188188
}
189189

190+
BOOST_AUTO_TEST_CASE(descriptorMetadataFields)
191+
{
192+
const auto database = getTempFile("Statement-descriptorMetadataFields.fdb");
193+
194+
Attachment attachment{CLIENT, database, AttachmentOptions().setCreateDatabase(true)};
195+
FbDropDatabase attachmentDrop{attachment};
196+
197+
Transaction transaction{attachment};
198+
199+
Statement createTable{attachment, transaction,
200+
"create table test_meta ("
201+
" id integer not null,"
202+
" name varchar(100),"
203+
" amount numeric(18, 2),"
204+
" data blob sub_type text"
205+
")"};
206+
createTable.execute(transaction);
207+
transaction.commit();
208+
209+
Transaction transaction2{attachment};
210+
211+
Statement select{attachment, transaction2, "select t.id as pk, t.name as label, t.amount, t.data from test_meta t"};
212+
213+
const auto& descriptors = select.getOutputDescriptors();
214+
BOOST_REQUIRE_EQUAL(descriptors.size(), 4U);
215+
216+
// Column 0: t.id as pk
217+
BOOST_CHECK_EQUAL(descriptors[0].name, "ID");
218+
BOOST_CHECK_EQUAL(descriptors[0].alias, "PK");
219+
BOOST_CHECK_EQUAL(descriptors[0].relation, "TEST_META");
220+
BOOST_CHECK(descriptors[0].subType == 0);
221+
222+
// Column 1: t.name as label
223+
BOOST_CHECK_EQUAL(descriptors[1].name, "NAME");
224+
BOOST_CHECK_EQUAL(descriptors[1].alias, "LABEL");
225+
BOOST_CHECK_EQUAL(descriptors[1].relation, "TEST_META");
226+
BOOST_CHECK(descriptors[1].adjustedType == DescriptorAdjustedType::STRING);
227+
228+
// Column 2: t.amount (no alias, numeric)
229+
BOOST_CHECK_EQUAL(descriptors[2].name, "AMOUNT");
230+
BOOST_CHECK_EQUAL(descriptors[2].alias, "AMOUNT");
231+
BOOST_CHECK_EQUAL(descriptors[2].relation, "TEST_META");
232+
233+
// Column 3: t.data (blob sub_type text)
234+
BOOST_CHECK_EQUAL(descriptors[3].name, "DATA");
235+
BOOST_CHECK_EQUAL(descriptors[3].alias, "DATA");
236+
BOOST_CHECK_EQUAL(descriptors[3].relation, "TEST_META");
237+
BOOST_CHECK_EQUAL(descriptors[3].subType, 1);
238+
239+
// Input descriptors for a parameterized query
240+
Statement paramSelect{attachment, transaction2, "select t.id from test_meta t where t.id = ?"};
241+
242+
const auto& inDescriptors = paramSelect.getInputDescriptors();
243+
BOOST_REQUIRE_EQUAL(inDescriptors.size(), 1U);
244+
245+
// Input parameters have empty name/relation/alias
246+
BOOST_CHECK(inDescriptors[0].name.empty());
247+
BOOST_CHECK(inDescriptors[0].relation.empty());
248+
BOOST_CHECK(inDescriptors[0].alias.empty());
249+
}
250+
190251
BOOST_AUTO_TEST_SUITE_END()
191252

192253

0 commit comments

Comments
 (0)