Skip to content

Commit 2c6b678

Browse files
committed
break load_es_types() in smaller functions
load_es_types() got too large.
1 parent 5b65ebd commit 2c6b678

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
@@ -102,6 +102,49 @@ typedef struct {
102102
wstr_st trace_level;
103103
} config_attrs_st;
104104

105+
/* structure for one row returned by the ES.
106+
* This is a mirror of elasticsearch_type, with length-or-indicator fields
107+
* for each of the members in elasticsearch_type */
108+
typedef struct {
109+
SQLWCHAR type_name[ESODBC_MAX_IDENTIFIER_LEN];
110+
SQLLEN type_name_loi; /* _ length or indicator */
111+
SQLSMALLINT data_type;
112+
SQLLEN data_type_loi;
113+
SQLINTEGER column_size;
114+
SQLLEN column_size_loi;
115+
SQLWCHAR literal_prefix[ESODBC_MAX_IDENTIFIER_LEN];
116+
SQLLEN literal_prefix_loi;
117+
SQLWCHAR literal_suffix[ESODBC_MAX_IDENTIFIER_LEN];
118+
SQLLEN literal_suffix_loi;
119+
SQLWCHAR create_params[ESODBC_MAX_IDENTIFIER_LEN];
120+
SQLLEN create_params_loi;
121+
SQLSMALLINT nullable;
122+
SQLLEN nullable_loi;
123+
SQLSMALLINT case_sensitive;
124+
SQLLEN case_sensitive_loi;
125+
SQLSMALLINT searchable;
126+
SQLLEN searchable_loi;
127+
SQLSMALLINT unsigned_attribute;
128+
SQLLEN unsigned_attribute_loi;
129+
SQLSMALLINT fixed_prec_scale;
130+
SQLLEN fixed_prec_scale_loi;
131+
SQLSMALLINT auto_unique_value;
132+
SQLLEN auto_unique_value_loi;
133+
SQLWCHAR local_type_name[ESODBC_MAX_IDENTIFIER_LEN];
134+
SQLLEN local_type_name_loi;
135+
SQLSMALLINT minimum_scale;
136+
SQLLEN minimum_scale_loi;
137+
SQLSMALLINT maximum_scale;
138+
SQLLEN maximum_scale_loi;
139+
SQLSMALLINT sql_data_type;
140+
SQLLEN sql_data_type_loi;
141+
SQLSMALLINT sql_datetime_sub;
142+
SQLLEN sql_datetime_sub_loi;
143+
SQLINTEGER num_prec_radix;
144+
SQLLEN num_prec_radix_loi;
145+
SQLSMALLINT interval_precision;
146+
SQLLEN interval_precision_loi;
147+
} estype_row_st;
105148
/*
106149
* HTTP headers used for all requests (Content-Type, Accept).
107150
*/
@@ -1355,6 +1398,141 @@ static void set_display_size(esodbc_estype_st *es_type)
13551398
}
13561399
}
13571400

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

14231559
if (! SQL_SUCCEEDED(EsSQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt))) {
14241560
ERRH(dbc, "failed to alloc a statement handle.");
@@ -1488,41 +1624,9 @@ static BOOL load_es_types(esodbc_dbc_st *dbc)
14881624
goto end;
14891625
}
14901626

1491-
/* bind one column */
1492-
#define ES_TYPES_BINDCOL(_col_nr, _member, _c_type) \
1493-
do { \
1494-
SQLPOINTER _ptr = _c_type == SQL_C_WCHAR ? \
1495-
(SQLPOINTER)(uintptr_t)type_row[0]._member : \
1496-
(SQLPOINTER)&type_row[0]._member; \
1497-
if (! SQL_SUCCEEDED(EsSQLBindCol(stmt, _col_nr, _c_type, \
1498-
_ptr, sizeof(type_row[0]._member), \
1499-
&type_row[0]._member ## _loi))) { \
1500-
ERRH(stmt, "failed to bind column #" STR(_col_nr) "."); \
1501-
goto end; \
1502-
} \
1503-
} while (0)
1504-
1505-
ES_TYPES_BINDCOL(1, type_name, SQL_C_WCHAR);
1506-
ES_TYPES_BINDCOL(2, data_type, SQL_C_SSHORT);
1507-
ES_TYPES_BINDCOL(3, column_size, SQL_C_SLONG);
1508-
ES_TYPES_BINDCOL(4, literal_prefix, SQL_C_WCHAR);
1509-
ES_TYPES_BINDCOL(5, literal_suffix, SQL_C_WCHAR);
1510-
ES_TYPES_BINDCOL(6, create_params, SQL_C_WCHAR);
1511-
ES_TYPES_BINDCOL(7, nullable, SQL_C_SSHORT);
1512-
ES_TYPES_BINDCOL(8, case_sensitive, SQL_C_SSHORT);
1513-
ES_TYPES_BINDCOL(9, searchable, SQL_C_SSHORT);
1514-
ES_TYPES_BINDCOL(10, unsigned_attribute, SQL_C_SSHORT);
1515-
ES_TYPES_BINDCOL(11, fixed_prec_scale, SQL_C_SSHORT);
1516-
ES_TYPES_BINDCOL(12, auto_unique_value, SQL_C_SSHORT);
1517-
ES_TYPES_BINDCOL(13, local_type_name, SQL_C_WCHAR);
1518-
ES_TYPES_BINDCOL(14, minimum_scale, SQL_C_SSHORT);
1519-
ES_TYPES_BINDCOL(15, maximum_scale, SQL_C_SSHORT);
1520-
ES_TYPES_BINDCOL(16, sql_data_type, SQL_C_SSHORT);
1521-
ES_TYPES_BINDCOL(17, sql_datetime_sub, SQL_C_SSHORT);
1522-
ES_TYPES_BINDCOL(18, num_prec_radix, SQL_C_SLONG);
1523-
ES_TYPES_BINDCOL(19, interval_precision, SQL_C_SSHORT);
1524-
1525-
#undef ES_TYPES_BINDCOL
1627+
if (! bind_types_cols(stmt, type_row)) {
1628+
goto end;
1629+
}
15261630

15271631
/* fetch the results into the type_row array */
15281632
if (! SQL_SUCCEEDED(EsSQLFetch(stmt))) {
@@ -1574,90 +1678,10 @@ static BOOL load_es_types(esodbc_dbc_st *dbc)
15741678
goto end;
15751679
}
15761680

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

0 commit comments

Comments
 (0)