Skip to content

Commit dead3da

Browse files
committed
break load_es_types() in smaller functions
load_es_types() got too large.
1 parent 76b2491 commit dead3da

File tree

1 file changed

+187
-163
lines changed

1 file changed

+187
-163
lines changed

driver/connect.c

Lines changed: 187 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,49 @@ typedef struct {
113113
wstr_st trace_level;
114114
} config_attrs_st;
115115

116+
/* structure for one row returned by the ES.
117+
* This is a mirror of elasticsearch_type, with length-or-indicator fields
118+
* for each of the members in elasticsearch_type */
119+
typedef struct {
120+
SQLWCHAR type_name[ESODBC_MAX_IDENTIFIER_LEN];
121+
SQLLEN type_name_loi; /* _ length or indicator */
122+
SQLSMALLINT data_type;
123+
SQLLEN data_type_loi;
124+
SQLINTEGER column_size;
125+
SQLLEN column_size_loi;
126+
SQLWCHAR literal_prefix[ESODBC_MAX_IDENTIFIER_LEN];
127+
SQLLEN literal_prefix_loi;
128+
SQLWCHAR literal_suffix[ESODBC_MAX_IDENTIFIER_LEN];
129+
SQLLEN literal_suffix_loi;
130+
SQLWCHAR create_params[ESODBC_MAX_IDENTIFIER_LEN];
131+
SQLLEN create_params_loi;
132+
SQLSMALLINT nullable;
133+
SQLLEN nullable_loi;
134+
SQLSMALLINT case_sensitive;
135+
SQLLEN case_sensitive_loi;
136+
SQLSMALLINT searchable;
137+
SQLLEN searchable_loi;
138+
SQLSMALLINT unsigned_attribute;
139+
SQLLEN unsigned_attribute_loi;
140+
SQLSMALLINT fixed_prec_scale;
141+
SQLLEN fixed_prec_scale_loi;
142+
SQLSMALLINT auto_unique_value;
143+
SQLLEN auto_unique_value_loi;
144+
SQLWCHAR local_type_name[ESODBC_MAX_IDENTIFIER_LEN];
145+
SQLLEN local_type_name_loi;
146+
SQLSMALLINT minimum_scale;
147+
SQLLEN minimum_scale_loi;
148+
SQLSMALLINT maximum_scale;
149+
SQLLEN maximum_scale_loi;
150+
SQLSMALLINT sql_data_type;
151+
SQLLEN sql_data_type_loi;
152+
SQLSMALLINT sql_datetime_sub;
153+
SQLLEN sql_datetime_sub_loi;
154+
SQLINTEGER num_prec_radix;
155+
SQLLEN num_prec_radix_loi;
156+
SQLSMALLINT interval_precision;
157+
SQLLEN interval_precision_loi;
158+
} estype_row_st;
116159
/*
117160
* HTTP headers used for all requests (Content-Type, Accept).
118161
*/
@@ -1366,6 +1409,141 @@ static void set_display_size(esodbc_estype_st *es_type)
13661409
}
13671410
}
13681411

1412+
static BOOL bind_types_cols(esodbc_stmt_st *stmt, estype_row_st *type_row)
1413+
{
1414+
1415+
/* bind one column */
1416+
#define ES_TYPES_BINDCOL(_col_nr, _member, _c_type) \
1417+
do { \
1418+
SQLPOINTER _ptr = _c_type == SQL_C_WCHAR ? \
1419+
(SQLPOINTER)(uintptr_t)type_row[0]._member : \
1420+
(SQLPOINTER)&type_row[0]._member; \
1421+
if (! SQL_SUCCEEDED(EsSQLBindCol(stmt, _col_nr, _c_type, \
1422+
_ptr, sizeof(type_row[0]._member), \
1423+
&type_row[0]._member ## _loi))) { \
1424+
ERRH(stmt, "failed to bind column #" STR(_col_nr) "."); \
1425+
return FALSE; \
1426+
} \
1427+
} while (0)
1428+
1429+
ES_TYPES_BINDCOL(1, type_name, SQL_C_WCHAR);
1430+
ES_TYPES_BINDCOL(2, data_type, SQL_C_SSHORT);
1431+
ES_TYPES_BINDCOL(3, column_size, SQL_C_SLONG);
1432+
ES_TYPES_BINDCOL(4, literal_prefix, SQL_C_WCHAR);
1433+
ES_TYPES_BINDCOL(5, literal_suffix, SQL_C_WCHAR);
1434+
ES_TYPES_BINDCOL(6, create_params, SQL_C_WCHAR);
1435+
ES_TYPES_BINDCOL(7, nullable, SQL_C_SSHORT);
1436+
ES_TYPES_BINDCOL(8, case_sensitive, SQL_C_SSHORT);
1437+
ES_TYPES_BINDCOL(9, searchable, SQL_C_SSHORT);
1438+
ES_TYPES_BINDCOL(10, unsigned_attribute, SQL_C_SSHORT);
1439+
ES_TYPES_BINDCOL(11, fixed_prec_scale, SQL_C_SSHORT);
1440+
ES_TYPES_BINDCOL(12, auto_unique_value, SQL_C_SSHORT);
1441+
ES_TYPES_BINDCOL(13, local_type_name, SQL_C_WCHAR);
1442+
ES_TYPES_BINDCOL(14, minimum_scale, SQL_C_SSHORT);
1443+
ES_TYPES_BINDCOL(15, maximum_scale, SQL_C_SSHORT);
1444+
ES_TYPES_BINDCOL(16, sql_data_type, SQL_C_SSHORT);
1445+
ES_TYPES_BINDCOL(17, sql_datetime_sub, SQL_C_SSHORT);
1446+
ES_TYPES_BINDCOL(18, num_prec_radix, SQL_C_SLONG);
1447+
ES_TYPES_BINDCOL(19, interval_precision, SQL_C_SSHORT);
1448+
1449+
#undef ES_TYPES_BINDCOL
1450+
1451+
return TRUE;
1452+
}
1453+
1454+
static void* copy_types_rows(estype_row_st *type_row, SQLULEN rows_fetched,
1455+
esodbc_estype_st *types)
1456+
{
1457+
SQLWCHAR *pos;
1458+
int i;
1459+
1460+
/* start pointer where the strings will be copied in */
1461+
pos = (SQLWCHAR *)&types[rows_fetched];
1462+
1463+
/* copy one integer member */
1464+
#define ES_TYPES_COPY_INT(_member) \
1465+
do { \
1466+
if (type_row[i]._member ## _loi == SQL_NULL_DATA) { \
1467+
/*null->0 is harmless for cached types */\
1468+
types[i]._member = 0; \
1469+
} else { \
1470+
types[i]._member = type_row[i]._member; \
1471+
} \
1472+
} while (0)
1473+
/* copy one wstr_st member
1474+
* Note: it'll shift NULLs to empty strings, as most of the API asks for
1475+
* empty strings if data is unavailable ("unkown"). */
1476+
#define ES_TYPES_COPY_WSTR(_wmember) \
1477+
do { \
1478+
if (type_row[i]._wmember ## _loi == SQL_NULL_DATA) { \
1479+
types[i]._wmember.cnt = 0; \
1480+
types[i]._wmember.str = MK_WPTR(""); \
1481+
} else { \
1482+
types[i]._wmember.cnt = \
1483+
type_row[i]._wmember ## _loi / sizeof(SQLWCHAR); \
1484+
types[i]._wmember.str = pos; \
1485+
wmemcpy(types[i]._wmember.str, \
1486+
type_row[i]._wmember, types[i]._wmember.cnt + /*\0*/1); \
1487+
pos += types[i]._wmember.cnt + /*\0*/1; \
1488+
} \
1489+
} while (0)
1490+
1491+
for (i = 0; i < rows_fetched; i ++) {
1492+
/* copy data */
1493+
ES_TYPES_COPY_WSTR(type_name);
1494+
ES_TYPES_COPY_INT(data_type);
1495+
ES_TYPES_COPY_INT(column_size);
1496+
ES_TYPES_COPY_WSTR(literal_prefix);
1497+
ES_TYPES_COPY_WSTR(literal_suffix);
1498+
ES_TYPES_COPY_WSTR(create_params);
1499+
ES_TYPES_COPY_INT(nullable);
1500+
ES_TYPES_COPY_INT(case_sensitive);
1501+
ES_TYPES_COPY_INT(searchable);
1502+
ES_TYPES_COPY_INT(unsigned_attribute);
1503+
ES_TYPES_COPY_INT(fixed_prec_scale);
1504+
ES_TYPES_COPY_INT(auto_unique_value);
1505+
ES_TYPES_COPY_WSTR(local_type_name);
1506+
ES_TYPES_COPY_INT(minimum_scale);
1507+
ES_TYPES_COPY_INT(maximum_scale);
1508+
ES_TYPES_COPY_INT(sql_data_type);
1509+
ES_TYPES_COPY_INT(sql_datetime_sub);
1510+
ES_TYPES_COPY_INT(num_prec_radix);
1511+
ES_TYPES_COPY_INT(interval_precision);
1512+
1513+
/* apply any needed fixes */
1514+
1515+
/* warn if scales extremes are different */
1516+
if (types[i].maximum_scale != types[i].minimum_scale) {
1517+
ERR("type `" LWPDL "` returned with non-equal max/min "
1518+
"scale: %d/%d.", LWSTR(&types[i].type_name),
1519+
types[i].maximum_scale, types[i].minimum_scale);
1520+
}
1521+
1522+
/* resolve ES type to SQL C type */
1523+
types[i].c_concise_type = type_elastic2csql(&types[i].type_name);
1524+
if (types[i].c_concise_type == SQL_UNKNOWN_TYPE) {
1525+
/* ES version newer than driver's? */
1526+
ERR("failed to convert type name `" LWPDL "` to SQL C type.",
1527+
LWSTR(&types[i].type_name));
1528+
return NULL;
1529+
}
1530+
/* set meta type */
1531+
types[i].meta_type = concise_to_meta(types[i].c_concise_type,
1532+
/*C type -> AxD*/DESC_TYPE_ARD);
1533+
1534+
/* fix SQL_DATA_TYPE and SQL_DATETIME_SUB columns TODO: GH issue */
1535+
concise_to_type_code(types[i].data_type, &types[i].sql_data_type,
1536+
&types[i].sql_datetime_sub);
1537+
1538+
set_display_size(types + i);
1539+
}
1540+
1541+
#undef ES_TYPES_COPY_INT
1542+
#undef ES_TYPES_COPY_WCHAR
1543+
1544+
return pos;
1545+
}
1546+
13691547
/*
13701548
* Load SYS TYPES data.
13711549
*
@@ -1380,56 +1558,14 @@ static BOOL load_es_types(esodbc_dbc_st *dbc)
13801558
SQLRETURN ret = FALSE;
13811559
SQLSMALLINT col_cnt;
13821560
SQLLEN row_cnt;
1383-
/* structure for one row returned by the ES.
1384-
* This is a mirror of elasticsearch_type, with length-or-indicator fields
1385-
* for each of the members in elasticsearch_type */
1386-
struct {
1387-
SQLWCHAR type_name[ESODBC_MAX_IDENTIFIER_LEN];
1388-
SQLLEN type_name_loi; /* _ length or indicator */
1389-
SQLSMALLINT data_type;
1390-
SQLLEN data_type_loi;
1391-
SQLINTEGER column_size;
1392-
SQLLEN column_size_loi;
1393-
SQLWCHAR literal_prefix[ESODBC_MAX_IDENTIFIER_LEN];
1394-
SQLLEN literal_prefix_loi;
1395-
SQLWCHAR literal_suffix[ESODBC_MAX_IDENTIFIER_LEN];
1396-
SQLLEN literal_suffix_loi;
1397-
SQLWCHAR create_params[ESODBC_MAX_IDENTIFIER_LEN];
1398-
SQLLEN create_params_loi;
1399-
SQLSMALLINT nullable;
1400-
SQLLEN nullable_loi;
1401-
SQLSMALLINT case_sensitive;
1402-
SQLLEN case_sensitive_loi;
1403-
SQLSMALLINT searchable;
1404-
SQLLEN searchable_loi;
1405-
SQLSMALLINT unsigned_attribute;
1406-
SQLLEN unsigned_attribute_loi;
1407-
SQLSMALLINT fixed_prec_scale;
1408-
SQLLEN fixed_prec_scale_loi;
1409-
SQLSMALLINT auto_unique_value;
1410-
SQLLEN auto_unique_value_loi;
1411-
SQLWCHAR local_type_name[ESODBC_MAX_IDENTIFIER_LEN];
1412-
SQLLEN local_type_name_loi;
1413-
SQLSMALLINT minimum_scale;
1414-
SQLLEN minimum_scale_loi;
1415-
SQLSMALLINT maximum_scale;
1416-
SQLLEN maximum_scale_loi;
1417-
SQLSMALLINT sql_data_type;
1418-
SQLLEN sql_data_type_loi;
1419-
SQLSMALLINT sql_datetime_sub;
1420-
SQLLEN sql_datetime_sub_loi;
1421-
SQLINTEGER num_prec_radix;
1422-
SQLLEN num_prec_radix_loi;
1423-
SQLSMALLINT interval_precision;
1424-
SQLLEN interval_precision_loi;
1425-
} type_row[ESODBC_MAX_ROW_ARRAY_SIZE];
1426-
/* both arrays must use ESODBC_MAX_ROW_ARRAY_SIZE since no SQLFetch()
1561+
/* both arrays below must use ESODBC_MAX_ROW_ARRAY_SIZE since no SQLFetch()
14271562
* looping is implemented (see check after SQLFetch() below). */
1563+
estype_row_st type_row[ESODBC_MAX_ROW_ARRAY_SIZE];
14281564
SQLUSMALLINT row_status[ESODBC_MAX_ROW_ARRAY_SIZE];
14291565
SQLULEN rows_fetched, i, strs_len;
14301566
size_t size;
1431-
SQLWCHAR *pos;
14321567
esodbc_estype_st *types = NULL;
1568+
void *pos;
14331569

14341570
if (! SQL_SUCCEEDED(EsSQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt))) {
14351571
ERRH(dbc, "failed to alloc a statement handle.");
@@ -1499,41 +1635,9 @@ static BOOL load_es_types(esodbc_dbc_st *dbc)
14991635
goto end;
15001636
}
15011637

1502-
/* bind one column */
1503-
#define ES_TYPES_BINDCOL(_col_nr, _member, _c_type) \
1504-
do { \
1505-
SQLPOINTER _ptr = _c_type == SQL_C_WCHAR ? \
1506-
(SQLPOINTER)(uintptr_t)type_row[0]._member : \
1507-
(SQLPOINTER)&type_row[0]._member; \
1508-
if (! SQL_SUCCEEDED(EsSQLBindCol(stmt, _col_nr, _c_type, \
1509-
_ptr, sizeof(type_row[0]._member), \
1510-
&type_row[0]._member ## _loi))) { \
1511-
ERRH(stmt, "failed to bind column #" STR(_col_nr) "."); \
1512-
goto end; \
1513-
} \
1514-
} while (0)
1515-
1516-
ES_TYPES_BINDCOL(1, type_name, SQL_C_WCHAR);
1517-
ES_TYPES_BINDCOL(2, data_type, SQL_C_SSHORT);
1518-
ES_TYPES_BINDCOL(3, column_size, SQL_C_SLONG);
1519-
ES_TYPES_BINDCOL(4, literal_prefix, SQL_C_WCHAR);
1520-
ES_TYPES_BINDCOL(5, literal_suffix, SQL_C_WCHAR);
1521-
ES_TYPES_BINDCOL(6, create_params, SQL_C_WCHAR);
1522-
ES_TYPES_BINDCOL(7, nullable, SQL_C_SSHORT);
1523-
ES_TYPES_BINDCOL(8, case_sensitive, SQL_C_SSHORT);
1524-
ES_TYPES_BINDCOL(9, searchable, SQL_C_SSHORT);
1525-
ES_TYPES_BINDCOL(10, unsigned_attribute, SQL_C_SSHORT);
1526-
ES_TYPES_BINDCOL(11, fixed_prec_scale, SQL_C_SSHORT);
1527-
ES_TYPES_BINDCOL(12, auto_unique_value, SQL_C_SSHORT);
1528-
ES_TYPES_BINDCOL(13, local_type_name, SQL_C_WCHAR);
1529-
ES_TYPES_BINDCOL(14, minimum_scale, SQL_C_SSHORT);
1530-
ES_TYPES_BINDCOL(15, maximum_scale, SQL_C_SSHORT);
1531-
ES_TYPES_BINDCOL(16, sql_data_type, SQL_C_SSHORT);
1532-
ES_TYPES_BINDCOL(17, sql_datetime_sub, SQL_C_SSHORT);
1533-
ES_TYPES_BINDCOL(18, num_prec_radix, SQL_C_SLONG);
1534-
ES_TYPES_BINDCOL(19, interval_precision, SQL_C_SSHORT);
1535-
1536-
#undef ES_TYPES_BINDCOL
1638+
if (! bind_types_cols(stmt, type_row)) {
1639+
goto end;
1640+
}
15371641

15381642
/* fetch the results into the type_row array */
15391643
if (! SQL_SUCCEEDED(EsSQLFetch(stmt))) {
@@ -1585,90 +1689,10 @@ static BOOL load_es_types(esodbc_dbc_st *dbc)
15851689
goto end;
15861690
}
15871691

1588-
/* start pointer where the strings will be copied in */
1589-
pos = (SQLWCHAR *)&types[rows_fetched];
1590-
1591-
/* copy one integer member
1592-
* TODO: treat NULL case */
1593-
#define ES_TYPES_COPY_INT(_member) \
1594-
do { \
1595-
if (type_row[i]._member ## _loi == SQL_NULL_DATA) { \
1596-
types[i]._member = 0; \
1597-
} else { \
1598-
types[i]._member = type_row[i]._member; \
1599-
} \
1600-
} while (0)
1601-
/* copy one wstr_st member
1602-
* Note: it'll shift NULLs to empty strings, as most of the API asks for
1603-
* empty strings if data is unavailable ("unkown"). */
1604-
#define ES_TYPES_COPY_WSTR(_wmember) \
1605-
do { \
1606-
if (type_row[i]._wmember ## _loi == SQL_NULL_DATA) { \
1607-
types[i]._wmember.cnt = 0; \
1608-
types[i]._wmember.str = MK_WPTR(""); \
1609-
} else { \
1610-
types[i]._wmember.cnt = \
1611-
type_row[i]._wmember ## _loi / sizeof(SQLWCHAR); \
1612-
types[i]._wmember.str = pos; \
1613-
wmemcpy(types[i]._wmember.str, \
1614-
type_row[i]._wmember, types[i]._wmember.cnt + /*\0*/1); \
1615-
pos += types[i]._wmember.cnt + /*\0*/1; \
1616-
} \
1617-
} while (0)
1618-
1619-
for (i = 0; i < rows_fetched; i ++) {
1620-
/* copy data */
1621-
ES_TYPES_COPY_WSTR(type_name);
1622-
ES_TYPES_COPY_INT(data_type);
1623-
ES_TYPES_COPY_INT(column_size);
1624-
ES_TYPES_COPY_WSTR(literal_prefix);
1625-
ES_TYPES_COPY_WSTR(literal_suffix);
1626-
ES_TYPES_COPY_WSTR(create_params);
1627-
ES_TYPES_COPY_INT(nullable);
1628-
ES_TYPES_COPY_INT(case_sensitive);
1629-
ES_TYPES_COPY_INT(searchable);
1630-
ES_TYPES_COPY_INT(unsigned_attribute);
1631-
ES_TYPES_COPY_INT(fixed_prec_scale);
1632-
ES_TYPES_COPY_INT(auto_unique_value);
1633-
ES_TYPES_COPY_WSTR(local_type_name);
1634-
ES_TYPES_COPY_INT(minimum_scale);
1635-
ES_TYPES_COPY_INT(maximum_scale);
1636-
ES_TYPES_COPY_INT(sql_data_type);
1637-
ES_TYPES_COPY_INT(sql_datetime_sub);
1638-
ES_TYPES_COPY_INT(num_prec_radix);
1639-
ES_TYPES_COPY_INT(interval_precision);
1640-
1641-
/* apply any needed fixes */
1642-
1643-
/* warn if scales extremes are different */
1644-
if (types[i].maximum_scale != types[i].minimum_scale) {
1645-
ERRH(dbc, "type `" LWPDL "` returned with non-equal max/min "
1646-
"scale: %d/%d.", LWSTR(&types[i].type_name),
1647-
types[i].maximum_scale, types[i].minimum_scale);
1648-
}
1649-
1650-
/* resolve ES type to SQL C type */
1651-
types[i].c_concise_type = type_elastic2csql(&types[i].type_name);
1652-
if (types[i].c_concise_type == SQL_UNKNOWN_TYPE) {
1653-
/* ES version newer than driver's? */
1654-
ERRH(dbc, "failed to convert type name `" LWPDL "` to SQL C type.",
1655-
LWSTR(&types[i].type_name));
1656-
goto end;
1657-
}
1658-
/* set meta type */
1659-
types[i].meta_type = concise_to_meta(types[i].c_concise_type,
1660-
/*C type -> AxD*/DESC_TYPE_ARD);
1661-
1662-
/* fix SQL_DATA_TYPE and SQL_DATETIME_SUB columns TODO: GH issue */
1663-
concise_to_type_code(types[i].data_type, &types[i].sql_data_type,
1664-
&types[i].sql_datetime_sub);
1665-
1666-
set_display_size(types + i);
1692+
if (! (pos = copy_types_rows(type_row, rows_fetched, types))) {
1693+
ERRH(dbc, "failed to process recieved ES/SQL data types.");
1694+
goto end;
16671695
}
1668-
1669-
#undef ES_TYPES_COPY_INT
1670-
#undef ES_TYPES_COPY_WCHAR
1671-
16721696
/* I didn't overrun the buffer */
16731697
assert((char *)pos - (char *)(types + rows_fetched) <=
16741698
(intptr_t)(strs_len));

0 commit comments

Comments
 (0)