Skip to content

Commit dea7946

Browse files
committed
addressed review comments
1 parent a1b0603 commit dea7946

File tree

2 files changed

+397
-15
lines changed

2 files changed

+397
-15
lines changed

mssql_python/cursor.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,30 @@ def _build_converter_map(self):
845845

846846
return converter_map
847847

848+
def _get_column_and_converter_maps(self):
849+
"""
850+
Get column map and converter map for Row construction (thread-safe).
851+
This centralizes the column map building logic to eliminate duplication
852+
and ensure thread-safe lazy initialization.
853+
854+
Returns:
855+
tuple: (column_map, converter_map)
856+
"""
857+
# Thread-safe lazy initialization of column map
858+
column_map = self._cached_column_map
859+
if column_map is None and self.description:
860+
# Build column map locally first, then assign to cache
861+
column_map = {col_desc[0]: i for i, col_desc in enumerate(self.description)}
862+
self._cached_column_map = column_map
863+
864+
# Fallback to legacy column name map if no cached map
865+
column_map = column_map or getattr(self, '_column_name_map', None)
866+
867+
# Get cached converter map
868+
converter_map = getattr(self, '_cached_converter_map', None)
869+
870+
return column_map, converter_map
871+
848872
def _map_data_type(self, sql_type):
849873
"""
850874
Map SQL data type to Python data type.
@@ -1985,11 +2009,8 @@ def fetchone(self) -> Union[None, Row]:
19852009

19862010
self.rowcount = self._next_row_index
19872011

1988-
# Build column map once and cache it
1989-
if self._cached_column_map is None and self.description:
1990-
self._cached_column_map = {col_desc[0]: i for i, col_desc in enumerate(self.description)}
1991-
column_map = self._cached_column_map or getattr(self, '_column_name_map', None)
1992-
converter_map = getattr(self, '_cached_converter_map', None)
2012+
# Get column and converter maps
2013+
column_map, converter_map = self._get_column_and_converter_maps()
19932014
return Row(row_data, column_map, cursor=self, converter_map=converter_map)
19942015
except Exception as e:
19952016
# On error, don't increment rownumber - rethrow the error
@@ -2035,13 +2056,10 @@ def fetchmany(self, size: Optional[int] = None) -> List[Row]:
20352056
else:
20362057
self.rowcount = self._next_row_index
20372058

2038-
# Build column map once and cache it
2039-
if self._cached_column_map is None and self.description:
2040-
self._cached_column_map = {col_desc[0]: i for i, col_desc in enumerate(self.description)}
2059+
# Get column and converter maps
2060+
column_map, converter_map = self._get_column_and_converter_maps()
20412061

20422062
# Convert raw data to Row objects
2043-
column_map = self._cached_column_map or getattr(self, '_column_name_map', None)
2044-
converter_map = getattr(self, '_cached_converter_map', None)
20452063
return [Row(row_data, column_map, cursor=self, converter_map=converter_map) for row_data in rows_data]
20462064
except Exception as e:
20472065
# On error, don't increment rownumber - rethrow the error
@@ -2077,13 +2095,10 @@ def fetchall(self) -> List[Row]:
20772095
else:
20782096
self.rowcount = self._next_row_index
20792097

2080-
# Build column map once and cache it
2081-
if self._cached_column_map is None and self.description:
2082-
self._cached_column_map = {col_desc[0]: i for i, col_desc in enumerate(self.description)}
2098+
# Get column and converter maps
2099+
column_map, converter_map = self._get_column_and_converter_maps()
20832100

20842101
# Convert raw data to Row objects
2085-
column_map = self._cached_column_map or getattr(self, '_column_name_map', None)
2086-
converter_map = getattr(self, '_cached_converter_map', None)
20872102
return [Row(row_data, column_map, cursor=self, converter_map=converter_map) for row_data in rows_data]
20882103
except Exception as e:
20892104
# On error, don't increment rownumber - rethrow the error

0 commit comments

Comments
 (0)