|
30 | 30 | from pgadmin.model import User |
31 | 31 | from pgadmin.utils.exception import ConnectionLost, CryptKeyMissing |
32 | 32 | from pgadmin.utils import get_complete_file_path |
| 33 | +from pgadmin.utils.ajax import internal_server_error |
33 | 34 | from ..abstract import BaseConnection |
34 | 35 | from .cursor import DictCursor, AsyncDictCursor, AsyncDictServerCursor |
35 | | -from .typecast import register_global_typecasters,\ |
36 | | - register_string_typecasters, register_binary_typecasters, \ |
37 | | - register_array_to_string_typecasters, ALL_JSON_TYPES, \ |
38 | | - register_numeric_typecasters |
| 36 | +from .typecast import register_binary_data_typecasters,\ |
| 37 | + register_global_typecasters, register_string_typecasters,\ |
| 38 | + register_binary_typecasters, register_array_to_string_typecasters,\ |
| 39 | + register_numeric_typecasters, ALL_JSON_TYPES |
39 | 40 | from .encoding import get_encoding, configure_driver_encodings |
40 | 41 | from pgadmin.utils import csv_lib as csv |
41 | 42 | from pgadmin.utils.master_password import get_crypt_key |
@@ -1913,3 +1914,43 @@ def mogrify(self, query, parameters): |
1913 | 1914 | return _cur.mogrify(query, parameters) |
1914 | 1915 | else: |
1915 | 1916 | return query |
| 1917 | + |
| 1918 | + def download_binary_data(self, cur, params): |
| 1919 | + """ |
| 1920 | + This function will return the binary data for the given query. |
| 1921 | + :param cur: cursor object |
| 1922 | + :param params: row/col params |
| 1923 | + :return: |
| 1924 | + """ |
| 1925 | + try: |
| 1926 | + register_binary_data_typecasters(cur) |
| 1927 | + row_pos = int(params['rowpos']) |
| 1928 | + col_pos = int(params['colpos']) |
| 1929 | + if row_pos < 0 or col_pos < 0: |
| 1930 | + raise ValueError |
| 1931 | + |
| 1932 | + # Save the current cursor position |
| 1933 | + saved_pos = cur.rownumber if cur.rownumber is not None else 0 |
| 1934 | + |
| 1935 | + try: |
| 1936 | + # Scroll to the requested row and fetch it |
| 1937 | + cur.scroll(row_pos, mode='absolute') |
| 1938 | + row = cur.fetchone() |
| 1939 | + finally: |
| 1940 | + # Always restore the cursor position |
| 1941 | + cur.scroll(saved_pos, mode='absolute') |
| 1942 | + |
| 1943 | + if row is None or col_pos >= len(row): |
| 1944 | + return internal_server_error( |
| 1945 | + errormsg=gettext('Requested cell is out of range.') |
| 1946 | + ) |
| 1947 | + return row[col_pos] |
| 1948 | + except (ValueError, IndexError, TypeError) as e: |
| 1949 | + current_app.logger.error(e) |
| 1950 | + return internal_server_error( |
| 1951 | + errormsg='Invalid row/column position.' |
| 1952 | + ) |
| 1953 | + finally: |
| 1954 | + # Always restore the original typecasters |
| 1955 | + # (works on connection or cursor) |
| 1956 | + register_binary_typecasters(cur) |
0 commit comments