emmental/emmental/db/settings.py

108 lines
3.6 KiB
Python

# Copyright 2022 (c) Anna Schumaker.
"""Easy access to the settings table in our database."""
import sqlite3
from gi.repository import GObject
from . import table
class Setting(table.Row):
"""Base class for settings."""
key = GObject.Property(type=str)
@property
def primary_key(self) -> str:
"""Get the primary key for this setting."""
return self.key
class IntSetting(Setting):
"""An integer setting."""
value = GObject.Property(type=int)
class FloatSetting(Setting):
"""A float setting."""
value = GObject.Property(type=float)
class BoolSetting(Setting):
"""A boolean setting."""
value = GObject.Property(type=bool, default=False)
class StringSetting(Setting):
"""A string setting."""
value = GObject.Property(type=str)
class Table(table.Table):
"""Creates and manages our settings properties."""
def __getitem__(self, key: str) -> int | float | str | bool | None:
"""Get the value for a specific settings key."""
if (setting := self.lookup(key)) is not None:
return setting.value
def do_construct(self, type: str, value: any, **kwargs) -> table.Row:
"""Construct a new settings row."""
match type:
case "gint":
return IntSetting(value=int(value), **kwargs)
case "gdouble":
return FloatSetting(value=float(value), **kwargs)
case "gboolean":
value = str(value) == "True"
return BoolSetting(value=value, **kwargs)
case "gchararray":
return StringSetting(value=value, **kwargs)
def do_get_sort_key(self, setting: table.Row) -> list[str]:
"""Get the sort key for a specific setting."""
return setting.key.casefold().split(".")
def do_sql_delete(self, setting: table.Row) -> sqlite3.Cursor:
"""Delete a setting."""
return self.sql("DELETE FROM settings WHERE key=?", setting.key)
def do_sql_glob(self, glob: str) -> sqlite3.Cursor:
"""Filter the settings table."""
return self.sql("""SELECT key FROM settings
WHERE CASEFOLD(key) GLOB ?""", glob)
def do_sql_insert(self, key: str, type: str, value) -> sqlite3.Cursor:
"""Create a new settings row."""
return self.sql("""INSERT INTO settings (key, type, value)
VALUES (?, ?, ?) RETURNING *""",
key, type, str(value))
def do_sql_select_all(self) -> sqlite3.Cursor:
"""Load settings from the database."""
return self.sql("SELECT * FROM settings ORDER BY CASEFOLD(key)")
def do_sql_select_one(self, key: str) -> int | None:
"""Look up a setting by key."""
return self.sql("SELECT key FROM settings WHERE key=?", key)
def do_sql_update(self, setting: table.Row, column: str,
newval: any) -> sqlite3.Cursor:
"""Update a Setting."""
return self.sql(f"UPDATE settings SET {column}=? WHERE key=?",
str(newval), setting.key)
def bind_setting(self, key: str, target: GObject.GObject,
property: str) -> None:
"""Bind a setting to a target property."""
if (setting := self.lookup(key=key)) is None:
param = target.find_property(property)
setting = self.create(key=key, type=param.value_type.name,
value=target.get_property(property))
else:
target.set_property(property, setting.value)
setting.bind_property("value", target, property,
GObject.BindingFlags.BIDIRECTIONAL)