diff --git a/osbot_utils/helpers/sqlite/Sqlite__Database.py b/osbot_utils/helpers/sqlite/Sqlite__Database.py index 9f51703b..ec7adae5 100644 --- a/osbot_utils/helpers/sqlite/Sqlite__Database.py +++ b/osbot_utils/helpers/sqlite/Sqlite__Database.py @@ -124,10 +124,12 @@ def tables(self): def tables_raw(self): return self.cursor().tables() - def tables_names(self, include_sqlite_master=False): + def tables_names(self, include_sqlite_master=False, include_indexes=True): table_names = self.table__sqlite_master().select_field_values('name') if include_sqlite_master: table_names.append('sqlite_master') + if include_indexes is False: + return [table_name for table_name in table_names if table_name.startswith('idx') is False] return table_names def purge_database(self): # this fells like a better name than vacuum :) diff --git a/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py b/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py new file mode 100644 index 00000000..5f502eca --- /dev/null +++ b/osbot_utils/helpers/sqlite/domains/Sqlite__DB.py @@ -0,0 +1,34 @@ +from typing import Dict, Type + +from osbot_utils.decorators.methods.cache_on_self import cache_on_self +from osbot_utils.helpers.sqlite.Sqlite__Database import Sqlite__Database +from osbot_utils.helpers.sqlite.tables.Sqlite__Table__Config import Sqlite__Table__Config, SQLITE__TABLE_NAME__CONFIG, \ + Schema__Table__Config + + +class Sqlite__DB(Sqlite__Database): + + # methods to override + def tables_to_add(self): # use this to define the tables that should be automatically created on setup + return {} + + def db_not_configured(self): + return self.tables_names() == [] + + @cache_on_self + def table_config(self): + return Sqlite__Table__Config(database=self) + + + + def tables_names(self, include_sqlite_master=False, include_indexes=False): + return super().tables_names(include_sqlite_master=include_sqlite_master, include_indexes=include_indexes) + + def setup(self): + if self.db_not_configured(): + self.table_config().setup() + for table_name, row_schema in self.tables_to_add().items(): + table = self.table(table_name) + table.row_schema = row_schema + table.create() + return self diff --git a/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py b/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py index 767c8e5e..a06dca04 100644 --- a/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py +++ b/osbot_utils/helpers/sqlite/domains/Sqlite__DB__Files.py @@ -21,11 +21,18 @@ def delete_file(self, path): def file(self, path, include_contents=False): return self.table_files().file(path, include_contents=include_contents) + def file_contents(self, path): + return self.table_files().file_contents(path) + + def file__with_content(self, path): + return self.file(path, include_contents=True) + def file_exists(self, path): return self.table_files().file_exists(path) def file_names(self): return self.table_files().select_field_values('path') + @cache_on_self def table_files(self): return Sqlite__Table__Files(database=self).setup() diff --git a/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py b/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py index 6e03a1fb..45080565 100644 --- a/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py +++ b/osbot_utils/helpers/sqlite/tables/Sqlite__Table__Files.py @@ -67,6 +67,12 @@ def file(self, path, include_contents=True): fields = self.field_names_without_content() return self.row(where=dict(path=path), fields = fields) + def file_contents(self, path): + fields = ['contents'] + row = self.row(where=dict(path=path), fields = fields) + if row: + return row.get('contents') + def file_without_contents(self, path): return self.file(path, include_contents=False) diff --git a/tests/unit/base_classes/test_Type_Safe__bugs.py b/tests/unit/base_classes/test_Type_Safe__bugs.py index 27bef2b2..51191109 100644 --- a/tests/unit/base_classes/test_Type_Safe__bugs.py +++ b/tests/unit/base_classes/test_Type_Safe__bugs.py @@ -10,6 +10,24 @@ class test_Type_Safe__bugs(TestCase): + def test__bug__type_safe_is_not_enforced_on_dict_and_Dict(self): + class An_Class(Type_Safe): + an_dict : dict[str:int] + + an_class = An_Class() + + assert An_Class.__annotations__ == {'an_dict': dict[slice(str, int, None)]} + assert an_class.__locals__() == {'an_dict': {}} + assert type(an_class.an_dict) is dict # BUG: this should be Type_Safe__Dict # todo: see if there is a better way to do this, without needing to replace the Dict object with Type_Safe__Dict (although this technique worked ok for Type_Safe__List) + an_class.an_dict[42] = 'an_str' # BUG: this should not be allowed + # - using key 42 should have raised exception (it is an int instead of a str) + # - using value 'an_str' should have raised exception (it is a str instead of an int) + + + + + + def test__bug__check_type_safety_assignments__on_ctor(self): an_bool_value = True an_int_value = 42 diff --git a/tests/unit/helpers/sqlite/domains/test__Sqlite__DB.py b/tests/unit/helpers/sqlite/domains/test__Sqlite__DB.py new file mode 100644 index 00000000..fd268fbf --- /dev/null +++ b/tests/unit/helpers/sqlite/domains/test__Sqlite__DB.py @@ -0,0 +1,33 @@ +from unittest import TestCase + +from osbot_utils.helpers.sqlite.Sqlite__Database import Sqlite__Database +from osbot_utils.helpers.sqlite.domains.Sqlite__DB import Sqlite__DB +from osbot_utils.utils.Dev import pprint + + +class test_Sqlite__DB(TestCase): + + @classmethod + def setUpClass(cls): + cls.sqlite_db = Sqlite__DB().setup() + + def test__init__(self): + with self.sqlite_db as _: + default_vars = Sqlite__Database().__attr_names__() + expected_vars = default_vars + + assert _.__attr_names__() == sorted(expected_vars) + assert _.tables_names(include_indexes=False) == ['config'] + + def test_table_config(self): + with self.sqlite_db.table_config() as _: + assert _.exists() is True + assert _.table_name == 'config' + assert _.data() == {} + + def test_setup(self): + with self.sqlite_db as _: + assert _.exists() is True + assert _.in_memory is True + assert _.db_path is None + assert _.tables_names() == ['config']