| 53 | |
| 54 | |
| 55 | class CLISessionDatabaseConnection: |
| 56 | _CREATE_TABLE = """ |
| 57 | CREATE TABLE IF NOT EXISTS session ( |
| 58 | key TEXT PRIMARY KEY, |
| 59 | session_id TEXT NOT NULL, |
| 60 | timestamp INTEGER NOT NULL |
| 61 | ) |
| 62 | """ |
| 63 | _CREATE_HOST_ID_TABLE = """ |
| 64 | CREATE TABLE IF NOT EXISTS host_id ( |
| 65 | key INTEGER PRIMARY KEY, |
| 66 | id TEXT UNIQUE NOT NULL |
| 67 | ) |
| 68 | """ |
| 69 | _CHECK_HOST_ID = """ |
| 70 | SELECT COUNT(*) FROM host_id |
| 71 | """ |
| 72 | _INSERT_HOST_ID = """ |
| 73 | INSERT OR IGNORE INTO host_id ( |
| 74 | key, id |
| 75 | ) VALUES (?, ?) |
| 76 | """ |
| 77 | _ENABLE_WAL = 'PRAGMA journal_mode=WAL' |
| 78 | |
| 79 | def __init__(self, connection=None, cache_dir=None): |
| 80 | self._cache_dir = cache_dir or _CACHE_DIR |
| 81 | self._ensure_cache_dir() |
| 82 | self._connection = connection or sqlite3.connect( |
| 83 | self._cache_dir / _DATABASE_FILENAME, |
| 84 | check_same_thread=False, |
| 85 | isolation_level=None, |
| 86 | ) |
| 87 | self._ensure_database_setup() |
| 88 | |
| 89 | def execute(self, query, *parameters): |
| 90 | try: |
| 91 | return self._connection.execute(query, *parameters) |
| 92 | except sqlite3.OperationalError: |
| 93 | # Process timed out waiting for database lock. |
| 94 | # Return any empty `Cursor` object instead of |
| 95 | # raising an exception. |
| 96 | return sqlite3.Cursor(self._connection) |
| 97 | |
| 98 | def _ensure_cache_dir(self): |
| 99 | self._cache_dir.mkdir(parents=True, exist_ok=True) |
| 100 | |
| 101 | def _ensure_database_setup(self): |
| 102 | self._create_session_table() |
| 103 | self._create_host_id_table() |
| 104 | self._ensure_host_id() |
| 105 | self._try_to_enable_wal() |
| 106 | |
| 107 | def _create_session_table(self): |
| 108 | self.execute(self._CREATE_TABLE) |
| 109 | |
| 110 | def _create_host_id_table(self): |
| 111 | self.execute(self._CREATE_HOST_ID_TABLE) |
| 112 |
no outgoing calls