sqlite-database 0.7.2__tar.gz → 0.7.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.github/workflows/python-publish.yml +1 -0
  2. {sqlite_database-0.7.2/sqlite_database.egg-info → sqlite_database-0.7.3}/PKG-INFO +1 -1
  3. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/pyproject.toml +1 -1
  4. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/__init__.py +3 -3
  5. {sqlite_database-0.7.2/sqlite_database/model → sqlite_database-0.7.3/sqlite_database/models}/__init__.py +27 -4
  6. {sqlite_database-0.7.2/sqlite_database/model → sqlite_database-0.7.3/sqlite_database/models}/errors.py +12 -9
  7. {sqlite_database-0.7.2/sqlite_database/model → sqlite_database-0.7.3/sqlite_database/models}/helpers.py +3 -3
  8. {sqlite_database-0.7.2/sqlite_database/model → sqlite_database-0.7.3/sqlite_database/models}/query_builder.py +18 -5
  9. {sqlite_database-0.7.2 → sqlite_database-0.7.3/sqlite_database.egg-info}/PKG-INFO +1 -1
  10. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database.egg-info/SOURCES.txt +5 -5
  11. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/tests/test_database.py +27 -4
  12. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.editorconfig +0 -0
  13. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  15. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.github/ISSUE_TEMPLATE/question.md +0 -0
  16. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.github/dependabot.yml +0 -0
  17. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.github/workflows/pylint.yml +0 -0
  18. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.github/workflows/pytest.yml +0 -0
  19. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.gitignore +0 -0
  20. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.readthedocs.yaml +0 -0
  21. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/.vscode/settings.json +0 -0
  22. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/Features.md +0 -0
  23. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/History.md +0 -0
  24. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/LICENSE +0 -0
  25. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/README.md +0 -0
  26. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/SimpleGuide.md +0 -0
  27. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/TODO.md +0 -0
  28. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/bin/activate +0 -0
  29. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/bin/check.bat +0 -0
  30. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/bin/check.sh +0 -0
  31. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/bin/include/utility.bash +0 -0
  32. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/bin/install.bash +0 -0
  33. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/bin/need-installed/activate +0 -0
  34. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/bin/need-installed/pre-commit +0 -0
  35. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/bin/summarize-pylint.py +0 -0
  36. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/dev-config/black.toml +0 -0
  37. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/dev-config/pylint.toml +0 -0
  38. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/dev-config/pytest.ini +0 -0
  39. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/dev-requirements.txt +0 -0
  40. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/Makefile +0 -0
  41. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/SimpleGuide.md +0 -0
  42. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/api_reference.rst +0 -0
  43. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/conf.py +0 -0
  44. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/index.rst +0 -0
  45. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/make.bat +0 -0
  46. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/modules.rst +0 -0
  47. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.column.rst +0 -0
  48. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.config.rst +0 -0
  49. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.csv.rst +0 -0
  50. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.database.rst +0 -0
  51. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.errors.rst +0 -0
  52. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.functions.rst +0 -0
  53. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.locals.rst +0 -0
  54. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.model.errors.rst +0 -0
  55. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.model.helpers.rst +0 -0
  56. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.model.query_builder.rst +0 -0
  57. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.model.rst +0 -0
  58. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.operators.rst +0 -0
  59. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.query_builder.rst +0 -0
  60. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.rst +0 -0
  61. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.signature.rst +0 -0
  62. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.subexp.rst +0 -0
  63. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.table.rst +0 -0
  64. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.typings.rst +0 -0
  65. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/sqlite_database.utils.rst +0 -0
  66. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs/usage.md +0 -0
  67. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/docs-requirements.txt +0 -0
  68. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/project-init.bash +0 -0
  69. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/setup.cfg +0 -0
  70. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/setup.py +0 -0
  71. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/_debug.py +0 -0
  72. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/_utils.py +0 -0
  73. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/column.py +0 -0
  74. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/csv.py +0 -0
  75. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/database.py +0 -0
  76. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/errors.py +0 -0
  77. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/functions.py +0 -0
  78. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/locals.py +0 -0
  79. {sqlite_database-0.7.2/sqlite_database/model → sqlite_database-0.7.3/sqlite_database/models}/mixin.py +0 -0
  80. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/operators.py +0 -0
  81. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/query_builder.py +0 -0
  82. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/signature.py +0 -0
  83. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/subquery.py +0 -0
  84. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/table.py +0 -0
  85. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/typings.py +0 -0
  86. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database/utils.py +0 -0
  87. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database.egg-info/dependency_links.txt +0 -0
  88. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database.egg-info/requires.txt +0 -0
  89. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database.egg-info/top_level.txt +0 -0
  90. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/sqlite_database.egg-info/zip-safe +0 -0
  91. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/tests/__init__.py +0 -0
  92. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/tests/manual_test_performances.py +0 -0
  93. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/tests/test_internals.py +0 -0
  94. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/tests/user_benchmark.py +0 -0
  95. {sqlite_database-0.7.2 → sqlite_database-0.7.3}/tests/user_helpers.py +0 -0
@@ -11,6 +11,7 @@ name: Upload Python Package
11
11
  on:
12
12
  release:
13
13
  types: [published]
14
+ workflow_dispatch:
14
15
 
15
16
  permissions:
16
17
  contents: read
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlite_database
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: A weird wrapper for SQLite Connection
5
5
  Home-page: https://github.com/RimuEirnarn/sqlite_database
6
6
  Author: RimuEirnarn
@@ -25,7 +25,7 @@ Repository = "https://github.com/RimuEirnarn/sqlite_database.git"
25
25
 
26
26
  [tool.setuptools]
27
27
  zip-safe = true
28
- packages = ["sqlite_database", "sqlite_database.model"]
28
+ packages = ["sqlite_database", "sqlite_database.models"]
29
29
 
30
30
  [project.optional-dependencies]
31
31
  dev = ["pytest", "pylint", "black"]
@@ -1,6 +1,6 @@
1
1
  """Database"""
2
2
 
3
- from .model import BaseModel, model, Foreign, Primary, Unique
3
+ from .models import BaseModel, model, Foreign, Primary, Unique
4
4
  from .database import Database
5
5
  from ._utils import null, Row, Null
6
6
  from .column import Column, text, integer, blob, real
@@ -14,7 +14,7 @@ def test_installed():
14
14
  return True
15
15
 
16
16
 
17
- __version__ = "0.7.2"
17
+ __version__ = "0.7.3"
18
18
  __all__ = [
19
19
  "Database",
20
20
  "Table",
@@ -29,7 +29,7 @@ __all__ = [
29
29
  "real",
30
30
  "blob",
31
31
  "BaseModel",
32
- "model",
32
+ "models",
33
33
  "Foreign",
34
34
  "Primary",
35
35
  "Unique"
@@ -210,6 +210,12 @@ class BaseModel: # pylint: disable=too-few-public-methods,too-many-public-metho
210
210
  """Delete multiple records using a primary key."""
211
211
  cls._tbl.delete({key: in_(keys)})
212
212
 
213
+ @classmethod
214
+ def first_or_fail(cls, **kwargs):
215
+ """Return the first matching record or raise an error if no match is found."""
216
+ result = cls.where(**kwargs).limit(1).throw().fetch_one()
217
+ return result
218
+
213
219
  @classmethod
214
220
  def first(cls, **kwargs):
215
221
  """Return the first matching record or None if no match is found."""
@@ -224,6 +230,18 @@ class BaseModel: # pylint: disable=too-few-public-methods,too-many-public-metho
224
230
  raise ValueError(f"Expected one record, but found {len(results)}")
225
231
  return results[0] if results else None
226
232
 
233
+ @classmethod
234
+ def find(cls, amount: int):
235
+ """Return models relative to the amount"""
236
+ results = cls.query().limit(amount).fetch()
237
+ return results
238
+
239
+ @classmethod
240
+ def find_or_fail(cls, amount: int):
241
+ """Return models relative to the amount and when returned is equal to 0, throws an error"""
242
+ results = cls.query().limit(amount).throw().fetch()
243
+ return results
244
+
227
245
  @classmethod
228
246
  def all(cls):
229
247
  """Return all values from the table"""
@@ -261,7 +279,7 @@ class BaseModel: # pylint: disable=too-few-public-methods,too-many-public-metho
261
279
  return {k: v for k, v in instance.items() if k not in self.__hidden__}
262
280
  return {}
263
281
 
264
- def to_safe_instance(self):
282
+ def to_safe_instance(self) -> Self:
265
283
  """Wrap instance that complies with __hidden__."""
266
284
  if is_dataclass(self):
267
285
  dict_inst = asdict(self).items()
@@ -286,7 +304,7 @@ class BaseModel: # pylint: disable=too-few-public-methods,too-many-public-metho
286
304
  # Scan __schema__ of related model to find a Foreign key linking back
287
305
  for constraint in related.__schema__:
288
306
  if isinstance(constraint, Foreign):
289
- table_ref, _ = constraint.target.split("/")
307
+ table_ref, _ = constraint.target.split("/") # type: ignore
290
308
  if table_ref == self.__class__.__name__.lower():
291
309
  foreign_key = constraint.column
292
310
  break
@@ -304,11 +322,11 @@ class BaseModel: # pylint: disable=too-few-public-methods,too-many-public-metho
304
322
  """Retrieve the related model that this instance belongs to."""
305
323
  # Find the Foreign() constraint that references `related_model`
306
324
  for constraint in self.__schema__:
307
- if isinstance(constraint, Foreign) and constraint.target.startswith(
325
+ if isinstance(constraint, Foreign) and constraint.target.startswith( # type: ignore
308
326
  related_model.__table_name__ + "/"
309
327
  ):
310
328
  foreign_key = constraint.column
311
- referenced_column = constraint.target.split("/")[1]
329
+ referenced_column = constraint.target.split("/")[1] # type: ignore
312
330
  return related_model.where(
313
331
  **{referenced_column: getattr(self, foreign_key)}
314
332
  ).fetch_one()
@@ -379,4 +397,9 @@ __all__ = [
379
397
  "Primary",
380
398
  "Foreign",
381
399
  "QueryBuilder",
400
+ "CASCADE",
401
+ "DEFAULT",
402
+ "NOACT",
403
+ "SETNULL",
404
+ "RESTRICT"
382
405
  ]
@@ -1,9 +1,12 @@
1
- """Error modules"""
2
-
3
- from ..errors import UnexpectedResultError
4
-
5
- class ValidationError(ValueError):
6
- """Specific validation error; a value fails validation test"""
7
-
8
- class ConstraintError(UnexpectedResultError):
9
- """Specific constraint is found twice, thrice, etc."""
1
+ """Error modules"""
2
+
3
+ from ..errors import UnexpectedResultError
4
+
5
+ class ValidationError(ValueError):
6
+ """Specific validation error; a value fails validation test"""
7
+
8
+ class ConstraintError(UnexpectedResultError):
9
+ """Specific constraint is found twice, thrice, etc."""
10
+
11
+ class NoDataReturnedError(ValueError):
12
+ """Data fetched from model cannot be retrieved"""
@@ -5,7 +5,7 @@ from typing import Any, Callable, Type, TypeAlias, TypeVar
5
5
  from enum import StrEnum
6
6
 
7
7
  import sqlite_database
8
- from sqlite_database.model.errors import ValidationError
8
+ from .errors import ValidationError
9
9
  from ..column import BuilderColumn, text, integer, blob, boolean
10
10
 
11
11
  TypeFunction: TypeAlias = Callable[[str], BuilderColumn]
@@ -80,7 +80,7 @@ class Foreign(Constraint):
80
80
 
81
81
  def resolve(self):
82
82
  """Resolve if current target is a Model"""
83
- if issubclass(self._target, sqlite_database.BaseModel):
83
+ if issubclass(self._target, sqlite_database.BaseModel): # type: ignore
84
84
  name = self._target.__table_name__
85
85
  target = self._target._primary # pylint: disable=protected-access
86
86
  if not target:
@@ -88,7 +88,7 @@ class Foreign(Constraint):
88
88
  self._target = f"{name}/{target}"
89
89
 
90
90
  def apply(self, type_: BuilderColumn):
91
- type_.foreign(self._target)
91
+ type_.foreign(self._target) # type: ignore
92
92
  if self._on_delete != DEFAULT:
93
93
  type_.on_delete(self._on_delete.value)
94
94
  if self._on_update != DEFAULT:
@@ -2,9 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
  from typing import Any, Generic, Type, TypeVar
5
+ from .errors import NoDataReturnedError
5
6
  from ..column import check_one
6
7
  from ..functions import Function
7
- from .. import model as models # pylint: disable=unused-import
8
+ from .. import models # pylint: disable=unused-import
8
9
 
9
10
  T = TypeVar("T", bound="models.BaseModel")
10
11
  count = Function('COUNT')
@@ -19,6 +20,12 @@ class QueryBuilder(Generic[T]):
19
20
  self._limit = 0
20
21
  self._offset = 0
21
22
  self._order = None
23
+ self._failing = False
24
+
25
+ def throw(self):
26
+ """Set when fetch() returns nothing, will raise an error"""
27
+ self._failing = True
28
+ return self
22
29
 
23
30
  def where(self, **kwargs):
24
31
  """Sets conditioning"""
@@ -42,19 +49,25 @@ class QueryBuilder(Generic[T]):
42
49
 
43
50
  def fetch(self) -> list[T]:
44
51
  """Fetch data from table"""
45
- return [
46
- self._model(**record)
47
- for record in self._model._tbl.select( # pylint: disable=protected-access
52
+ records = self._model._tbl.select( # pylint: disable=protected-access
48
53
  self._filters, limit=self._limit, offset=self._offset, order=self._order
49
54
  )
55
+ if len(records) == 0 and self._failing:
56
+ raise NoDataReturnedError(f"Model {self._model.__name__} has no data for current scope")
57
+ return [
58
+ self._model(**record) for record in records
50
59
  ]
51
60
 
52
- def fetch_one(self) -> T:
61
+ def fetch_one(self) -> T | None:
53
62
  """Fetch one data from table"""
54
63
  # pylint: disable=protected-access
55
64
  record = self._model._tbl.select_one(
56
65
  self._filters, order=self._order
57
66
  )
67
+ if not record and self._failing:
68
+ raise NoDataReturnedError(f"Model {self._model.__name__} has no data for current scope")
69
+ if not record:
70
+ return None
58
71
  return self._model(**record)
59
72
 
60
73
  def count(self) -> int:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlite_database
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: A weird wrapper for SQLite Connection
5
5
  Home-page: https://github.com/RimuEirnarn/sqlite_database
6
6
  Author: RimuEirnarn
@@ -81,11 +81,11 @@ sqlite_database.egg-info/dependency_links.txt
81
81
  sqlite_database.egg-info/requires.txt
82
82
  sqlite_database.egg-info/top_level.txt
83
83
  sqlite_database.egg-info/zip-safe
84
- sqlite_database/model/__init__.py
85
- sqlite_database/model/errors.py
86
- sqlite_database/model/helpers.py
87
- sqlite_database/model/mixin.py
88
- sqlite_database/model/query_builder.py
84
+ sqlite_database/models/__init__.py
85
+ sqlite_database/models/errors.py
86
+ sqlite_database/models/helpers.py
87
+ sqlite_database/models/mixin.py
88
+ sqlite_database/models/query_builder.py
89
89
  tests/__init__.py
90
90
  tests/manual_test_performances.py
91
91
  tests/test_database.py
@@ -15,9 +15,9 @@ from pytest import raises
15
15
 
16
16
  from sqlite_database._debug import STATE
17
17
  from sqlite_database import Column, Database, integer, text, Null
18
- from sqlite_database.model import Primary, Unique, model, BaseModel, Foreign, CASCADE
19
- from sqlite_database.model.errors import ValidationError
20
- from sqlite_database.model.mixin import ChunkableMixin, ScopeMixin
18
+ from sqlite_database.models import Primary, Unique, model, BaseModel, Foreign, CASCADE
19
+ from sqlite_database.models.errors import ValidationError, NoDataReturnedError
20
+ from sqlite_database.models.mixin import ChunkableMixin, ScopeMixin
21
21
  from sqlite_database.signature import op
22
22
  from sqlite_database.operators import eq, in_, this
23
23
  from sqlite_database.errors import TableRemovedError, CuteDemonLordException
@@ -384,7 +384,7 @@ def test_07_00_export_csv():
384
384
  database = Database(":memory:")
385
385
  setup_database(database)
386
386
  csv = to_csv_string(database)
387
- print("test_06_export_csv\n", csv, "\n", file=pstdout, flush=True)
387
+ print("test_07_00_export_csv\n", csv, "\n", file=pstdout, flush=True)
388
388
  assert csv
389
389
 
390
390
 
@@ -614,6 +614,29 @@ def test_11_05_model_hidden():
614
614
  assert "password" not in admin_dict
615
615
  assert admin.to_safe_instance().password is None
616
616
 
617
+ def test_11_06_model_fail():
618
+ """Test 1105 Model API __hidden__"""
619
+
620
+ db = Database(":memory:")
621
+
622
+ def auto_id():
623
+ return str(uuid4())
624
+
625
+ @model(db)
626
+ class Users(BaseModel):
627
+ """Base User class"""
628
+
629
+ __schema__ = (Primary("id"),)
630
+ __auto_id__ = auto_id
631
+ __hidden__ = ("password",)
632
+ id: str
633
+ username: str
634
+ password: str
635
+
636
+ Users.first()
637
+ with raises(NoDataReturnedError):
638
+ Users.find_or_fail(1)
639
+
617
640
  def test_98_00_test():
618
641
  """Gradual test"""
619
642
  db = Database(":memory:")
File without changes
File without changes