1 """The sql component."""
3 from __future__
import annotations
8 import voluptuous
as vol
13 DEVICE_CLASSES_SCHEMA,
22 CONF_UNIT_OF_MEASUREMENT,
35 from .const
import CONF_COLUMN_NAME, CONF_QUERY, DOMAIN, PLATFORMS
36 from .util
import redact_credentials
38 _LOGGER = logging.getLogger(__name__)
42 """Validate that value is a SQL SELECT query."""
43 if len(query := sqlparse.parse(value.lstrip().lstrip(
";"))) > 1:
44 raise vol.Invalid(
"Multiple SQL queries are not supported")
45 if len(query) == 0
or (query_type := query[0].get_type()) ==
"UNKNOWN":
46 raise vol.Invalid(
"Invalid SQL query")
47 if query_type !=
"SELECT":
48 _LOGGER.debug(
"The SQL query %s is of type %s", query, query_type)
49 raise vol.Invalid(
"Only SELECT queries allowed")
53 QUERY_SCHEMA = vol.Schema(
55 vol.Required(CONF_COLUMN_NAME): cv.string,
56 vol.Required(CONF_NAME): cv.template,
57 vol.Required(CONF_QUERY): vol.All(cv.string, validate_sql_select),
58 vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
59 vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
60 vol.Optional(CONF_UNIQUE_ID): cv.string,
61 vol.Optional(CONF_DB_URL): cv.string,
62 vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
63 vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA,
64 vol.Optional(CONF_AVAILABILITY): cv.template,
65 vol.Optional(CONF_ICON): cv.template,
66 vol.Optional(CONF_PICTURE): cv.template,
70 CONFIG_SCHEMA = vol.Schema(
71 {vol.Optional(DOMAIN): vol.All(cv.ensure_list, [QUERY_SCHEMA])},
72 extra=vol.ALLOW_EXTRA,
77 hass: HomeAssistant, entry: ConfigEntry
79 """Remove db url from config if it matches recorder database."""
80 hass.config_entries.async_update_entry(
83 key: value
for key, value
in entry.options.items()
if key != CONF_DB_URL
89 """Update listener for options."""
90 await hass.config_entries.async_reload(entry.entry_id)
93 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
94 """Set up SQL from yaml config."""
95 if (conf := config.get(DOMAIN))
is None:
98 for sensor_conf
in conf:
99 await discovery.async_load_platform(
100 hass, Platform.SENSOR, DOMAIN, sensor_conf, config
107 """Set up SQL from a config entry."""
109 "Comparing %s and %s",
113 if entry.options.get(CONF_DB_URL) ==
get_instance(hass).db_url:
116 entry.async_on_unload(entry.add_update_listener(async_update_listener))
118 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
124 """Unload SQL config entry."""
126 return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
None remove_configured_db_url_if_not_needed(HomeAssistant hass, ConfigEntry entry)
None async_update_listener(HomeAssistant hass, ConfigEntry entry)
bool async_setup(HomeAssistant hass, ConfigType config)
str validate_sql_select(str value)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
str redact_credentials(str url)
Recorder get_instance(HomeAssistant hass)