omlish 0.0.0.dev268__py3-none-any.whl → 0.0.0.dev270__py3-none-any.whl

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 (62) hide show
  1. omlish/__about__.py +2 -2
  2. omlish/bootstrap/marshal.py +4 -3
  3. omlish/dataclasses/__init__.py +7 -0
  4. omlish/dataclasses/impl/metaclass.py +1 -0
  5. omlish/dataclasses/impl/simple.py +1 -1
  6. omlish/formats/toml/parser.py +593 -594
  7. omlish/lang/classes/abstract.py +3 -0
  8. omlish/lang/comparison.py +3 -0
  9. omlish/lang/datetimes.py +3 -0
  10. omlish/lang/generators.py +2 -2
  11. omlish/lang/maybes.py +3 -0
  12. omlish/lang/resolving.py +3 -0
  13. omlish/lang/sys.py +3 -0
  14. omlish/marshal/__init__.py +16 -0
  15. omlish/marshal/base.py +230 -14
  16. omlish/marshal/composite/iterables.py +3 -0
  17. omlish/marshal/composite/literals.py +7 -4
  18. omlish/marshal/composite/mappings.py +3 -0
  19. omlish/marshal/composite/maybes.py +3 -0
  20. omlish/marshal/composite/newtypes.py +7 -4
  21. omlish/marshal/composite/optionals.py +7 -4
  22. omlish/marshal/composite/wrapped.py +3 -0
  23. omlish/marshal/global_.py +16 -0
  24. omlish/marshal/objects/dataclasses.py +5 -5
  25. omlish/marshal/objects/marshal.py +2 -2
  26. omlish/marshal/objects/namedtuples.py +4 -4
  27. omlish/marshal/objects/unmarshal.py +2 -2
  28. omlish/marshal/polymorphism/marshal.py +2 -2
  29. omlish/marshal/polymorphism/metadata.py +9 -3
  30. omlish/marshal/polymorphism/unions.py +6 -6
  31. omlish/marshal/polymorphism/unmarshal.py +2 -2
  32. omlish/marshal/singular/base64.py +3 -0
  33. omlish/marshal/singular/enums.py +7 -4
  34. omlish/marshal/singular/numbers.py +3 -0
  35. omlish/marshal/singular/uuids.py +3 -0
  36. omlish/marshal/standard.py +25 -3
  37. omlish/marshal/trivial/any.py +3 -0
  38. omlish/marshal/trivial/forbidden.py +13 -2
  39. omlish/marshal/trivial/nop.py +3 -0
  40. omlish/secrets/marshal.py +4 -6
  41. omlish/specs/jsonrpc/marshal.py +4 -5
  42. omlish/specs/openapi/marshal.py +4 -2
  43. omlish/sql/alchemy/__init__.py +31 -0
  44. omlish/sql/alchemy/apiadapter.py +121 -0
  45. omlish/sql/api/__init__.py +39 -0
  46. omlish/sql/api/base.py +1 -0
  47. omlish/sql/parsing/parsing.py +1 -1
  48. omlish/sql/queries/__init__.py +4 -0
  49. omlish/sql/queries/base.py +113 -2
  50. omlish/sql/queries/exprs.py +15 -2
  51. omlish/sql/queries/inserts.py +2 -1
  52. omlish/sql/queries/marshal.py +23 -9
  53. omlish/sql/queries/params.py +3 -2
  54. omlish/sql/queries/rendering.py +16 -4
  55. omlish/sql/queries/selects.py +17 -2
  56. omlish/sql/tabledefs/marshal.py +4 -2
  57. {omlish-0.0.0.dev268.dist-info → omlish-0.0.0.dev270.dist-info}/METADATA +1 -1
  58. {omlish-0.0.0.dev268.dist-info → omlish-0.0.0.dev270.dist-info}/RECORD +62 -61
  59. {omlish-0.0.0.dev268.dist-info → omlish-0.0.0.dev270.dist-info}/WHEEL +0 -0
  60. {omlish-0.0.0.dev268.dist-info → omlish-0.0.0.dev270.dist-info}/entry_points.txt +0 -0
  61. {omlish-0.0.0.dev268.dist-info → omlish-0.0.0.dev270.dist-info}/licenses/LICENSE +0 -0
  62. {omlish-0.0.0.dev268.dist-info → omlish-0.0.0.dev270.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@ from ... import lang
7
7
  from ... import reflect as rfl
8
8
  from ..base import MarshalContext
9
9
  from ..base import Marshaler
10
- from ..base import MarshalerFactory
10
+ from ..base import SimpleMarshalerFactory
11
11
  from ..values import Value
12
12
  from .metadata import FieldTypeTagging
13
13
  from .metadata import Impls
@@ -68,7 +68,7 @@ def make_polymorphism_marshaler(
68
68
 
69
69
 
70
70
  @dc.dataclass(frozen=True)
71
- class PolymorphismMarshalerFactory(MarshalerFactory):
71
+ class PolymorphismMarshalerFactory(SimpleMarshalerFactory):
72
72
  p: Polymorphism
73
73
  tt: TypeTagging = WrapperTypeTagging()
74
74
 
@@ -109,12 +109,11 @@ def polymorphism_from_subclasses(
109
109
  ty: type,
110
110
  *,
111
111
  naming: Naming | None = None,
112
- strip_suffix: bool = False,
112
+ strip_suffix: bool | ta.Literal['auto'] = False,
113
113
  ) -> Polymorphism:
114
- dct: dict[str, Impl] = {}
115
-
116
114
  seen: set[type] = set()
117
115
  todo: list[type] = [ty]
116
+ impls: set[type] = set()
118
117
  while todo:
119
118
  cur = todo.pop()
120
119
  seen.add(cur)
@@ -124,6 +123,13 @@ def polymorphism_from_subclasses(
124
123
  if lang.is_abstract_class(cur):
125
124
  continue
126
125
 
126
+ impls.add(cur)
127
+
128
+ if strip_suffix == 'auto':
129
+ strip_suffix = all(c.__name__.endswith(ty.__name__) for c in impls)
130
+
131
+ dct: dict[str, Impl] = {}
132
+ for cur in impls:
127
133
  name = cur.__name__
128
134
  if strip_suffix:
129
135
  name = lang.strip_suffix(name, ty.__name__)
@@ -8,10 +8,10 @@ from ... import reflect as rfl
8
8
  from ...funcs import match as mfs
9
9
  from ..base import MarshalContext
10
10
  from ..base import Marshaler
11
- from ..base import MarshalerFactory
11
+ from ..base import SimpleMarshalerFactory
12
+ from ..base import SimpleUnmarshalerFactory
12
13
  from ..base import UnmarshalContext
13
14
  from ..base import Unmarshaler
14
- from ..base import UnmarshalerFactory
15
15
  from ..values import Value
16
16
  from .marshal import make_polymorphism_marshaler
17
17
  from .metadata import Impls
@@ -69,7 +69,7 @@ class PrimitiveUnionMarshaler(Marshaler):
69
69
 
70
70
 
71
71
  @dc.dataclass(frozen=True)
72
- class PrimitiveUnionMarshalerFactory(MarshalerFactory):
72
+ class PrimitiveUnionMarshalerFactory(SimpleMarshalerFactory):
73
73
  tys: ta.Sequence[type] = PRIMITIVE_UNION_TYPES
74
74
 
75
75
  def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
@@ -94,7 +94,7 @@ class PrimitiveUnionUnmarshaler(Unmarshaler):
94
94
 
95
95
 
96
96
  @dc.dataclass(frozen=True)
97
- class PrimitiveUnionUnmarshalerFactory(UnmarshalerFactory):
97
+ class PrimitiveUnionUnmarshalerFactory(SimpleUnmarshalerFactory):
98
98
  tys: ta.Sequence[type] = PRIMITIVE_UNION_TYPES
99
99
 
100
100
  def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
@@ -140,12 +140,12 @@ class _BasePolymorphismUnionFactory(lang.Abstract):
140
140
 
141
141
 
142
142
  @dc.dataclass(frozen=True)
143
- class PolymorphismUnionMarshalerFactory(_BasePolymorphismUnionFactory, MarshalerFactory):
143
+ class PolymorphismUnionMarshalerFactory(_BasePolymorphismUnionFactory, SimpleMarshalerFactory):
144
144
  def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
145
145
  return make_polymorphism_marshaler(self.get_impls(rty), self.tt, ctx)
146
146
 
147
147
 
148
148
  @dc.dataclass(frozen=True)
149
- class PolymorphismUnionUnmarshalerFactory(_BasePolymorphismUnionFactory, UnmarshalerFactory):
149
+ class PolymorphismUnionUnmarshalerFactory(_BasePolymorphismUnionFactory, SimpleUnmarshalerFactory):
150
150
  def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
151
151
  return make_polymorphism_unmarshaler(self.get_impls(rty), self.tt, ctx)
@@ -6,9 +6,9 @@ import typing as ta
6
6
  from ... import check
7
7
  from ... import lang
8
8
  from ... import reflect as rfl
9
+ from ..base import SimpleUnmarshalerFactory
9
10
  from ..base import UnmarshalContext
10
11
  from ..base import Unmarshaler
11
- from ..base import UnmarshalerFactory
12
12
  from ..values import Value
13
13
  from .metadata import FieldTypeTagging
14
14
  from .metadata import Impls
@@ -75,7 +75,7 @@ def make_polymorphism_unmarshaler(
75
75
 
76
76
 
77
77
  @dc.dataclass(frozen=True)
78
- class PolymorphismUnmarshalerFactory(UnmarshalerFactory):
78
+ class PolymorphismUnmarshalerFactory(SimpleUnmarshalerFactory):
79
79
  p: Polymorphism
80
80
  tt: TypeTagging = WrapperTypeTagging()
81
81
 
@@ -19,6 +19,9 @@ from ..values import Value
19
19
  T = ta.TypeVar('T')
20
20
 
21
21
 
22
+ ##
23
+
24
+
22
25
  @dc.dataclass(frozen=True)
23
26
  class Base64MarshalerUnmarshaler(Marshaler, Unmarshaler, ta.Generic[T]):
24
27
  ty: type[T]
@@ -6,13 +6,16 @@ from ... import check
6
6
  from ... import reflect as rfl
7
7
  from ..base import MarshalContext
8
8
  from ..base import Marshaler
9
- from ..base import MarshalerFactory
9
+ from ..base import SimpleMarshalerFactory
10
+ from ..base import SimpleUnmarshalerFactory
10
11
  from ..base import UnmarshalContext
11
12
  from ..base import Unmarshaler
12
- from ..base import UnmarshalerFactory
13
13
  from ..values import Value
14
14
 
15
15
 
16
+ ##
17
+
18
+
16
19
  @dc.dataclass(frozen=True)
17
20
  class EnumMarshaler(Marshaler):
18
21
  ty: type[enum.Enum]
@@ -21,7 +24,7 @@ class EnumMarshaler(Marshaler):
21
24
  return o.name
22
25
 
23
26
 
24
- class EnumMarshalerFactory(MarshalerFactory):
27
+ class EnumMarshalerFactory(SimpleMarshalerFactory):
25
28
  def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
26
29
  return isinstance(rty, type) and issubclass(rty, enum.Enum)
27
30
 
@@ -39,7 +42,7 @@ class EnumUnmarshaler(Unmarshaler):
39
42
  return self.ty[check.isinstance(v, str)]
40
43
 
41
44
 
42
- class EnumUnmarshalerFactory(UnmarshalerFactory):
45
+ class EnumUnmarshalerFactory(SimpleUnmarshalerFactory):
43
46
  def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
44
47
  return isinstance(rty, type) and issubclass(rty, enum.Enum)
45
48
 
@@ -12,6 +12,9 @@ from ..base import Unmarshaler
12
12
  from ..values import Value
13
13
 
14
14
 
15
+ ##
16
+
17
+
15
18
  class ComplexMarshalerUnmarshaler(Marshaler, Unmarshaler):
16
19
  def marshal(self, ctx: MarshalContext, o: complex) -> Value:
17
20
  return [o.real, o.imag]
@@ -11,6 +11,9 @@ from ..base import Unmarshaler
11
11
  from ..values import Value
12
12
 
13
13
 
14
+ ##
15
+
16
+
14
17
  PATTERN = re.compile(r'([0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12})|([0-9A-Fa-f]{32})')
15
18
 
16
19
 
@@ -1,5 +1,6 @@
1
- from ..funcs import match as mfs
2
1
  from .base import MarshalerFactory
2
+ from .base import MultiMarshalerFactory
3
+ from .base import MultiUnmarshalerFactory
3
4
  from .base import RecursiveMarshalerFactory
4
5
  from .base import RecursiveUnmarshalerFactory
5
6
  from .base import TypeCacheMarshalerFactory
@@ -65,7 +66,7 @@ STANDARD_MARSHALER_FACTORIES: list[MarshalerFactory] = [
65
66
  def new_standard_marshaler_factory() -> MarshalerFactory:
66
67
  return TypeCacheMarshalerFactory(
67
68
  RecursiveMarshalerFactory(
68
- mfs.MultiMatchFn(
69
+ MultiMarshalerFactory(
69
70
  list(STANDARD_MARSHALER_FACTORIES),
70
71
  ),
71
72
  ),
@@ -98,8 +99,29 @@ STANDARD_UNMARSHALER_FACTORIES: list[UnmarshalerFactory] = [
98
99
  def new_standard_unmarshaler_factory() -> UnmarshalerFactory:
99
100
  return TypeCacheUnmarshalerFactory(
100
101
  RecursiveUnmarshalerFactory(
101
- mfs.MultiMatchFn(
102
+ MultiUnmarshalerFactory(
102
103
  list(STANDARD_UNMARSHALER_FACTORIES),
103
104
  ),
104
105
  ),
105
106
  )
107
+
108
+
109
+ ##
110
+
111
+
112
+ def install_standard_factories(
113
+ *factories: MarshalerFactory | UnmarshalerFactory,
114
+ ) -> None:
115
+ for f in factories:
116
+ k = False
117
+
118
+ if isinstance(f, MarshalerFactory):
119
+ STANDARD_MARSHALER_FACTORIES[0:0] = [f]
120
+ k = True
121
+
122
+ if isinstance(f, UnmarshalerFactory):
123
+ STANDARD_UNMARSHALER_FACTORIES[0:0] = [f]
124
+ k = True
125
+
126
+ if not k:
127
+ raise TypeError(f)
@@ -10,6 +10,9 @@ from ..base import Unmarshaler
10
10
  from ..values import Value
11
11
 
12
12
 
13
+ ##
14
+
15
+
13
16
  class AnyMarshalerUnmarshaler(Marshaler, Unmarshaler):
14
17
  def marshal(self, ctx: MarshalContext, o: ta.Any) -> Value:
15
18
  return ctx.make(type(o)).marshal(ctx, o)
@@ -5,6 +5,8 @@ from ... import reflect as rfl
5
5
  from ...funcs import match as mfs
6
6
  from ..base import MarshalContext
7
7
  from ..base import Marshaler
8
+ from ..base import SimpleMarshalerFactory
9
+ from ..base import SimpleUnmarshalerFactory
8
10
  from ..base import UnmarshalContext
9
11
  from ..base import Unmarshaler
10
12
  from ..exceptions import ForbiddenTypeError
@@ -14,6 +16,9 @@ C = ta.TypeVar('C')
14
16
  R = ta.TypeVar('R')
15
17
 
16
18
 
19
+ ##
20
+
21
+
17
22
  @dc.dataclass(frozen=True)
18
23
  class ForbiddenTypeFactory(mfs.MatchFn[[C, rfl.Type], R]):
19
24
  rtys: ta.AbstractSet[rfl.Type]
@@ -26,10 +31,16 @@ class ForbiddenTypeFactory(mfs.MatchFn[[C, rfl.Type], R]):
26
31
 
27
32
 
28
33
  @dc.dataclass(frozen=True)
29
- class ForbiddenTypeMarshalerFactory(ForbiddenTypeFactory[MarshalContext, Marshaler]):
34
+ class ForbiddenTypeMarshalerFactory(
35
+ ForbiddenTypeFactory[MarshalContext, Marshaler],
36
+ SimpleMarshalerFactory,
37
+ ):
30
38
  pass
31
39
 
32
40
 
33
41
  @dc.dataclass(frozen=True)
34
- class ForbiddenTypeUnmarshalerFactory(ForbiddenTypeFactory[UnmarshalContext, Unmarshaler]):
42
+ class ForbiddenTypeUnmarshalerFactory(
43
+ ForbiddenTypeFactory[UnmarshalContext, Unmarshaler],
44
+ SimpleUnmarshalerFactory,
45
+ ):
35
46
  pass
@@ -7,6 +7,9 @@ from ..base import Unmarshaler
7
7
  from ..values import Value
8
8
 
9
9
 
10
+ ##
11
+
12
+
10
13
  class NopMarshalerUnmarshaler(Marshaler, Unmarshaler):
11
14
  def marshal(self, ctx: MarshalContext, o: ta.Any) -> Value:
12
15
  return o # noqa
omlish/secrets/marshal.py CHANGED
@@ -52,16 +52,14 @@ def marshal_secret_field(f: dc.Field) -> dc.Field:
52
52
 
53
53
  @lang.static_init
54
54
  def _install_standard_marshalling() -> None:
55
- msh.STANDARD_MARSHALER_FACTORIES[0:0] = [
55
+ msh.install_standard_factories(
56
56
  msh.ForbiddenTypeMarshalerFactory({Secret}),
57
+ msh.ForbiddenTypeUnmarshalerFactory({Secret}),
58
+
57
59
  msh.TypeMapMarshalerFactory({
58
60
  rfl.type_(SecretRefOrStr): StrOrSecretRefMarshalerUnmarshaler(),
59
61
  }),
60
- ]
61
-
62
- msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [
63
- msh.ForbiddenTypeUnmarshalerFactory({Secret}),
64
62
  msh.TypeMapUnmarshalerFactory({
65
63
  rfl.type_(SecretRefOrStr): StrOrSecretRefMarshalerUnmarshaler(),
66
64
  }),
67
- ]
65
+ )
@@ -49,11 +49,10 @@ class NotSpecifiedUnionUnmarshalerFactory(msh.UnmarshalerFactoryMatchClass):
49
49
 
50
50
  @lang.static_init
51
51
  def _install_standard_marshalling() -> None:
52
- msh.STANDARD_MARSHALER_FACTORIES[0:0] = [
52
+ msh.install_standard_factories(
53
53
  msh.ForbiddenTypeMarshalerFactory({_NOT_SPECIFIED_RTY}),
54
- NotSpecifiedUnionMarshalerFactory(),
55
- ]
56
- msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [
57
54
  msh.ForbiddenTypeUnmarshalerFactory({_NOT_SPECIFIED_RTY}),
55
+
56
+ NotSpecifiedUnionMarshalerFactory(),
58
57
  NotSpecifiedUnionUnmarshalerFactory(),
59
- ]
58
+ )
@@ -59,5 +59,7 @@ class _ReferenceUnionUnmarshalerFactory(msh.UnmarshalerFactoryMatchClass):
59
59
 
60
60
  @lang.static_init
61
61
  def _install_standard_marshalling() -> None:
62
- msh.STANDARD_MARSHALER_FACTORIES[0:0] = [_ReferenceUnionMarshalerFactory()]
63
- msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [_ReferenceUnionUnmarshalerFactory()]
62
+ msh.install_standard_factories(
63
+ _ReferenceUnionMarshalerFactory(),
64
+ _ReferenceUnionUnmarshalerFactory(),
65
+ )
@@ -1,3 +1,34 @@
1
+ # ruff: noqa: I001
2
+ import typing as _ta
3
+
4
+ from ... import lang as _lang
5
+
6
+
7
+ if _ta.TYPE_CHECKING:
8
+ from .apiadapter import ( # noqa
9
+ SqlalchemyApiWrapper,
10
+
11
+ SqlalchemyApiRows,
12
+ SqlalchemyApiConn,
13
+ SqlalchemyApiDb,
14
+ SqlalchemyApiAdapter,
15
+
16
+ api_adapt,
17
+ )
18
+
19
+ else:
20
+ _lang.proxy_init(globals(), '.apiadapter', [
21
+ 'SqlalchemyApiWrapper',
22
+
23
+ 'SqlalchemyApiRows',
24
+ 'SqlalchemyApiConn',
25
+ 'SqlalchemyApiDb',
26
+ 'SqlalchemyApiAdapter',
27
+
28
+ 'api_adapt',
29
+ ])
30
+
31
+
1
32
  from .asyncs import ( # noqa
2
33
  AsyncConnection,
3
34
  AsyncConnectionLike,
@@ -0,0 +1,121 @@
1
+ import typing as ta
2
+
3
+ import sqlalchemy as sa
4
+
5
+ from ... import check
6
+ from .. import api
7
+ from ..api.dbapi import build_dbapi_columns
8
+
9
+
10
+ T = ta.TypeVar('T')
11
+
12
+
13
+ ##
14
+
15
+
16
+ class SqlalchemyApiWrapper(api.ContextCloser, ta.Generic[T]):
17
+ def __init__(
18
+ self,
19
+ u: T,
20
+ *,
21
+ auto_close: bool = False,
22
+ ) -> None:
23
+ super().__init__()
24
+
25
+ self._u = u
26
+ self._auto_close = auto_close
27
+
28
+ def close(self) -> None:
29
+ if self._auto_close and hasattr(self._u, 'close'):
30
+ self._u.close()
31
+ super().close()
32
+
33
+
34
+ ##
35
+
36
+
37
+ class SqlalchemyApiRows(api.Rows):
38
+ def __init__(self, columns: api.Columns, rows: ta.Sequence[api.Row]) -> None:
39
+ super().__init__()
40
+
41
+ self._columns = columns
42
+ self._rows = rows
43
+
44
+ self._it = iter(self._rows)
45
+
46
+ @property
47
+ def columns(self) -> api.Columns:
48
+ return self._columns
49
+
50
+ def __next__(self) -> api.Row:
51
+ return next(self._it)
52
+
53
+
54
+ class SqlalchemyApiConn(SqlalchemyApiWrapper[sa.engine.Connection], api.Conn):
55
+ @property
56
+ def adapter(self) -> api.Adapter:
57
+ raise NotImplementedError
58
+
59
+ def query(self, query: api.Query) -> api.Rows:
60
+ check.empty(query.args)
61
+ result: sa.engine.cursor.CursorResult
62
+ with self._u.execute(sa.text(query.text)) as result:
63
+ cols = build_dbapi_columns(result.cursor.description)
64
+ sa_rows = result.fetchall()
65
+ rows = [
66
+ api.Row(cols, tuple(sa_row))
67
+ for sa_row in sa_rows
68
+ ]
69
+ return SqlalchemyApiRows(cols, rows)
70
+
71
+
72
+ class SqlalchemyApiDb(SqlalchemyApiWrapper[sa.engine.Engine], api.Db):
73
+ def connect(self) -> api.Conn:
74
+ return SqlalchemyApiConn(self._u.connect(), auto_close=True)
75
+
76
+ @property
77
+ def adapter(self) -> api.Adapter:
78
+ raise NotImplementedError
79
+
80
+
81
+ class SqlalchemyApiAdapter(api.Adapter):
82
+ def scan_type(self, c: api.Column) -> type:
83
+ raise NotImplementedError
84
+
85
+
86
+ ##
87
+
88
+
89
+ @ta.overload
90
+ def api_adapt(o: sa.engine.Connection) -> SqlalchemyApiConn:
91
+ ...
92
+
93
+
94
+ @ta.overload
95
+ def api_adapt(o: api.Conn) -> api.Conn:
96
+ ...
97
+
98
+
99
+ @ta.overload
100
+ def api_adapt(o: sa.engine.Engine) -> SqlalchemyApiDb:
101
+ ...
102
+
103
+
104
+ @ta.overload
105
+ def api_adapt(o: api.Db) -> api.Db:
106
+ ...
107
+
108
+
109
+ def api_adapt(o):
110
+ if isinstance(o, sa.engine.Connection):
111
+ return SqlalchemyApiConn(o)
112
+ elif isinstance(o, api.Conn):
113
+ return o
114
+
115
+ elif isinstance(o, sa.engine.Engine):
116
+ return SqlalchemyApiDb(o)
117
+ elif isinstance(o, api.Db):
118
+ return o
119
+
120
+ else:
121
+ raise TypeError(o)
@@ -0,0 +1,39 @@
1
+ from .base import ( # noqa
2
+ Closer,
3
+ ContextCloser,
4
+
5
+ Querier,
6
+ Rows,
7
+ Conn,
8
+ Db,
9
+ Adapter,
10
+ )
11
+
12
+ from .columns import ( # noqa
13
+ Column,
14
+ Columns,
15
+ )
16
+
17
+ from .errors import ( # noqa
18
+ Error,
19
+
20
+ ColumnError,
21
+ DuplicateColumnNameError,
22
+ MismatchedColumnCountError,
23
+
24
+ QueryError,
25
+ )
26
+
27
+ from .funcs import ( # noqa
28
+ query,
29
+ exec, # noqa
30
+ )
31
+
32
+ from .queries import ( # noqa
33
+ QueryMode,
34
+ Query,
35
+ )
36
+
37
+ from .rows import ( # noqa
38
+ Row,
39
+ )
omlish/sql/api/base.py CHANGED
@@ -24,6 +24,7 @@ class ContextCloser(Closer):
24
24
  def __enter__(self) -> ta.Self:
25
25
  return self
26
26
 
27
+ @ta.final
27
28
  def __exit__(self, exc_type, exc_val, exc_tb):
28
29
  self.close()
29
30
 
@@ -33,7 +33,7 @@ class _ParseVisitor(MinisqlVisitor):
33
33
  def visitExprSelectItem(self, ctx: MinisqlParser.ExprSelectItemContext):
34
34
  value = self.visit(ctx.expr())
35
35
  label = self.visit(ctx.ident()) if ctx.ident() is not None else None
36
- return no.SelectItem(value, label)
36
+ return no.ExprSelectItem(value, label)
37
37
 
38
38
  def visitIntegerNumber(self, ctx: MinisqlParser.IntegerNumberContext):
39
39
  return no.Literal(int(ctx.INTEGER_VALUE().getText()))
@@ -1,6 +1,7 @@
1
1
  from .base import ( # noqa
2
2
  Builder,
3
3
  Node,
4
+ NodeComparisonTypeError,
4
5
  Value,
5
6
  )
6
7
 
@@ -18,6 +19,7 @@ from .exprs import ( # noqa
18
19
  ExprBuilder,
19
20
  Literal,
20
21
  NameExpr,
22
+ ParamExpr,
21
23
  )
22
24
 
23
25
  from .idents import ( # noqa
@@ -66,7 +68,9 @@ from .rendering import ( # noqa
66
68
  )
67
69
 
68
70
  from .selects import ( # noqa
71
+ AllSelectItem,
69
72
  CanRelation,
73
+ ExprSelectItem,
70
74
  Select,
71
75
  SelectBuilder,
72
76
  SelectItem,