-
-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add key binding to refresh data catalog * refactor: rename cache to editor_cache * feat: cache data catalog
- Loading branch information
Showing
15 changed files
with
358 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,8 @@ | ||
import pickle | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
from typing import List, Union | ||
""" | ||
This is required for backward-compatibility for previously-pickled caches. | ||
from platformdirs import user_cache_dir | ||
from textual_textarea.key_handlers import Cursor as Cursor | ||
cache.py was renamed to editor_cache.py when the Data Catalog cache was created. | ||
""" | ||
from harlequin.editor_cache import BufferState, Cache | ||
|
||
CACHE_VERSION = 0 | ||
|
||
|
||
@dataclass | ||
class BufferState: | ||
cursor: Cursor | ||
selection_anchor: Union[Cursor, None] | ||
text: str | ||
|
||
|
||
@dataclass | ||
class Cache: | ||
focus_index: int # currently doesn't impact focus on load | ||
buffers: List[BufferState] | ||
|
||
|
||
def get_cache_file() -> Path: | ||
""" | ||
Returns the path to the cache file on disk | ||
""" | ||
cache_dir = Path(user_cache_dir(appname="harlequin")) | ||
cache_file = cache_dir / f"cache-{CACHE_VERSION}.pickle" | ||
return cache_file | ||
|
||
|
||
def load_cache() -> Union[Cache, None]: | ||
""" | ||
Returns a Cache (a list of strings) by loading | ||
from a pickle saved to disk | ||
""" | ||
cache_file = get_cache_file() | ||
try: | ||
with cache_file.open("rb") as f: | ||
cache: Cache = pickle.load(f) | ||
assert isinstance(cache, Cache) | ||
except ( | ||
pickle.UnpicklingError, | ||
ValueError, | ||
IndexError, | ||
FileNotFoundError, | ||
AssertionError, | ||
): | ||
return None | ||
else: | ||
return cache | ||
|
||
|
||
def write_cache(cache: Cache) -> None: | ||
""" | ||
Updates dumps buffer contents to to disk | ||
""" | ||
cache_file = get_cache_file() | ||
cache_file.parent.mkdir(parents=True, exist_ok=True) | ||
with open(cache_file, "wb") as f: | ||
pickle.dump(cache, f) | ||
__all__ = ["BufferState", "Cache"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
from __future__ import annotations | ||
|
||
import hashlib | ||
import json | ||
import pickle | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
from typing import Any, Sequence | ||
|
||
from platformdirs import user_cache_dir | ||
from textual_textarea.key_handlers import Cursor as Cursor | ||
|
||
from harlequin.catalog import Catalog | ||
|
||
CACHE_VERSION = 0 | ||
|
||
|
||
class PermissiveEncoder(json.JSONEncoder): | ||
def default(self, obj: Any) -> Any: | ||
if isinstance(obj, Path): | ||
return str(obj) | ||
# Never raise a TypeError, just use the repr | ||
try: | ||
return str(obj) | ||
except TypeError: | ||
return "" | ||
|
||
|
||
@dataclass | ||
class CatalogCache: | ||
databases: dict[str, Catalog] | ||
|
||
|
||
def get_connection_hash(conn_str: Sequence[str], config: dict[str, Any]) -> str: | ||
return ( | ||
hashlib.md5( | ||
json.dumps( | ||
{"conn_str": tuple(conn_str), **config}, | ||
cls=PermissiveEncoder, | ||
).encode("utf-8") | ||
) | ||
.digest() | ||
.hex() | ||
) | ||
|
||
|
||
def get_cached_catalog(connection_hash: str) -> Catalog | None: | ||
cache = _load_cache() | ||
if cache is None: | ||
return None | ||
return cache.databases.get(connection_hash, None) | ||
|
||
|
||
def update_cache_with_catalog(connection_hash: str, catalog: Catalog) -> None: | ||
cache = _load_cache() | ||
if cache is None: | ||
cache = CatalogCache(databases={}) | ||
cache.databases[connection_hash] = catalog | ||
_write_cache(cache) | ||
|
||
|
||
def _get_cache_file() -> Path: | ||
""" | ||
Returns the path to the cache file on disk | ||
""" | ||
cache_dir = Path(user_cache_dir(appname="harlequin")) | ||
cache_file = cache_dir / f"catalog-cache-{CACHE_VERSION}.pickle" | ||
return cache_file | ||
|
||
|
||
def _load_cache() -> CatalogCache | None: | ||
""" | ||
Returns a Cache by loading from a pickle saved to disk | ||
""" | ||
cache_file = _get_cache_file() | ||
try: | ||
with cache_file.open("rb") as f: | ||
cache: CatalogCache = pickle.load(f) | ||
assert isinstance(cache, CatalogCache) | ||
except ( | ||
pickle.UnpicklingError, | ||
ValueError, | ||
IndexError, | ||
FileNotFoundError, | ||
AssertionError, | ||
): | ||
return None | ||
else: | ||
return cache | ||
|
||
|
||
def _write_cache(cache: CatalogCache) -> None: | ||
""" | ||
Updates cache with current data catalog | ||
""" | ||
cache_file = _get_cache_file() | ||
cache_file.parent.mkdir(parents=True, exist_ok=True) | ||
with open(cache_file, "wb") as f: | ||
pickle.dump(cache, f) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.