Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
_py_row.py129 linesDownload Raw Back to engine
1# engine/_py_row.py
2# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
7from __future__ import annotations
8
9import operator
10import typing
11from typing import Any
12from typing import Callable
13from typing import Dict
14from typing import Iterator
15from typing import List
16from typing import Mapping
17from typing import Optional
18from typing import Tuple
19from typing import Type
20
21if typing.TYPE_CHECKING:
22    from .result import _KeyType
23    from .result import _ProcessorsType
24    from .result import _RawRowType
25    from .result import _TupleGetterType
26    from .result import ResultMetaData
27
28MD_INDEX = 0  # integer index in cursor.description
29
30
31class BaseRow:
32    __slots__ = ("_parent", "_data", "_key_to_index")
33
34    _parent: ResultMetaData
35    _key_to_index: Mapping[_KeyType, int]
36    _data: _RawRowType
37
38    def __init__(
39        self,
40        parent: ResultMetaData,
41        processors: Optional[_ProcessorsType],
42        key_to_index: Mapping[_KeyType, int],
43        data: _RawRowType,
44    ):
45        """Row objects are constructed by CursorResult objects."""
46        object.__setattr__(self, "_parent", parent)
47
48        object.__setattr__(self, "_key_to_index", key_to_index)
49
50        if processors:
51            object.__setattr__(
52                self,
53                "_data",
54                tuple(
55                    [
56                        proc(value) if proc else value
57                        for proc, value in zip(processors, data)
58                    ]
59                ),
60            )
61        else:
62            object.__setattr__(self, "_data", tuple(data))
63
64    def __reduce__(self) -> Tuple[Callable[..., BaseRow], Tuple[Any, ...]]:
65        return (
66            rowproxy_reconstructor,
67            (self.__class__, self.__getstate__()),
68        )
69
70    def __getstate__(self) -> Dict[str, Any]:
71        return {"_parent": self._parent, "_data": self._data}
72
73    def __setstate__(self, state: Dict[str, Any]) -> None:
74        parent = state["_parent"]
75        object.__setattr__(self, "_parent", parent)
76        object.__setattr__(self, "_data", state["_data"])
77        object.__setattr__(self, "_key_to_index", parent._key_to_index)
78
79    def _values_impl(self) -> List[Any]:
80        return list(self)
81
82    def __iter__(self) -> Iterator[Any]:
83        return iter(self._data)
84
85    def __len__(self) -> int:
86        return len(self._data)
87
88    def __hash__(self) -> int:
89        return hash(self._data)
90
91    def __getitem__(self, key: Any) -> Any:
92        return self._data[key]
93
94    def _get_by_key_impl_mapping(self, key: str) -> Any:
95        try:
96            return self._data[self._key_to_index[key]]
97        except KeyError:
98            pass
99        self._parent._key_not_found(key, False)
100
101    def __getattr__(self, name: str) -> Any:
102        try:
103            return self._data[self._key_to_index[name]]
104        except KeyError:
105            pass
106        self._parent._key_not_found(name, True)
107
108    def _to_tuple_instance(self) -> Tuple[Any, ...]:
109        return self._data
110
111
112# This reconstructor is necessary so that pickles with the Cy extension or
113# without use the same Binary format.
114def rowproxy_reconstructor(
115    cls: Type[BaseRow], state: Dict[str, Any]
116) -> BaseRow:
117    obj = cls.__new__(cls)
118    obj.__setstate__(state)
119    return obj
120
121
122def tuplegetter(*indexes: int) -> _TupleGetterType:
123    if len(indexes) != 1:
124        for i in range(1, len(indexes)):
125            if indexes[i - 1] != indexes[i] - 1:
126                return operator.itemgetter(*indexes)
127    # slice form is faster but returns a list if input is list
128    return operator.itemgetter(slice(indexes[0], indexes[-1] + 1))
129 
codekingpro/portable-devtools · Team Ai