Files
zeekay 75dd1132bd rename: zero ClickHouse — datastore_connect speaks X-Datastore-*
The wire protocol was the last holdout and it was not cosmetic: the Hanzo
Datastore server reads X-Datastore-User, and answers a request bearing
X-ClickHouse-User with 401. Verified against the live server, both directions.
So a client still sending the old headers is not merely off-brand, it cannot
authenticate over HTTP.

Everything else follows: types, dialects, error modules, docstrings and doc
links now name Datastore, and doc URLs point at docs.hanzo.ai/datastore rather
than the upstream vendor's site. Zero occurrences of the old name remain.

Still cut from the pinned upstream version, so behaviour is unchanged.
2026-07-26 11:06:05 -07:00

88 lines
3.0 KiB
Python

import getpass
import sys
from dataclasses import dataclass
from typing import Any, Sequence, Optional, Dict
from datastore_connect import __version__
from datastore_connect.driver.exceptions import ProgrammingError
def version():
return __version__.version
def format_error(msg: str) -> str:
max_size = _common_settings['max_error_size'].value
if max_size:
return msg[:max_size]
return msg
@dataclass
class CommonSetting:
name: str
options: Sequence[Any]
default: Any
value: Optional[Any] = None
_common_settings: Dict[str, CommonSetting] = {}
def build_client_name(client_name: str):
product_name = get_setting('product_name')
product_name = product_name.strip() + ' ' if product_name else ''
client_name = client_name.strip() + ' ' if client_name else ''
py_version = sys.version.split(' ', maxsplit=1)[0]
os_user = ''
if get_setting('send_os_user'):
try:
os_user = f'; os_user:{getpass.getuser()}'
except Exception: # pylint: disable=broad-except
pass
full_name = (f'{client_name}{product_name}datastore-connect/{version()}' +
f' (lv:py/{py_version}; mode:sync; os:{sys.platform}{os_user})')
return full_name.encode('ascii', 'ignore').decode()
def get_setting(name: str):
setting = _common_settings.get(name)
if setting is None:
raise ProgrammingError(f'Unrecognized common setting {name}')
return setting.value if setting.value is not None else setting.default
def set_setting(name: str, value: Any):
setting = _common_settings.get(name)
if setting is None:
raise ProgrammingError(f'Unrecognized common setting {name}')
if setting.options and value not in setting.options:
raise ProgrammingError(f'Unrecognized option {value} for setting {name})')
if value == setting.default:
setting.value = None
else:
setting.value = value
def _init_common(name: str, options: Sequence[Any], default: Any):
_common_settings[name] = CommonSetting(name, options, default)
_init_common('autogenerate_session_id', (True, False), True)
_init_common('dict_parameter_format', ('json', 'map'), 'json')
_init_common('invalid_setting_action', ('send', 'drop', 'error'), 'error')
_init_common('max_connection_age', (), 10 * 60) # Max time in seconds to keep reusing a database TCP connection
_init_common('product_name', (), '') # Product name used as part of client identification for Datastore query_log
_init_common('readonly', (0, 1), 0) # Implied "read_only" Datastore settings for versions prior to 19.17
_init_common('send_os_user', (True, False), True)
# Use the client protocol version This is needed for DateTime timezone columns but breaks with current version of
# chproxy
_init_common('use_protocol_version', (True, False), True)
_init_common('max_error_size', (), 1024)
# HTTP raw data buffer for streaming queries. This should not be reduced below 64KB to ensure compatibility with LZ4 compression
_init_common('http_buffer_size', (), 10 * 1024 * 1024)