omlish 0.0.0.dev297__py3-none-any.whl → 0.0.0.dev299__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.
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev297'
2
- __revision__ = '60d7844496d6c1b510da1f34cb05a64b5f8c1f6d'
1
+ __version__ = '0.0.0.dev299'
2
+ __revision__ = '73b5419aa5d43e554a35a615d906559440e76d1b'
3
3
 
4
4
 
5
5
  #
omlish/argparse/cli.py CHANGED
@@ -9,6 +9,7 @@ TODO:
9
9
  - auto match all underscores to hyphens
10
10
  - pre-run, post-run hooks
11
11
  - exitstack?
12
+ - suggestion - difflib.get_close_matches
12
13
  """
13
14
  import argparse
14
15
  import dataclasses as dc
omlish/lang/functions.py CHANGED
@@ -211,6 +211,9 @@ class Args:
211
211
  self.args = args
212
212
  self.kwargs = kwargs
213
213
 
214
+ def __bool__(self) -> bool:
215
+ return bool(self.args) or bool(self.kwargs)
216
+
214
217
  def update(self, *args: ta.Any, **kwargs: ta.Any) -> 'Args':
215
218
  return Args(
216
219
  *self.args,
omlish/secrets/all.py CHANGED
@@ -23,4 +23,5 @@ ref = SecretRef
23
23
 
24
24
  from ..lang.imports import _register_conditional_import # noqa
25
25
 
26
+ # FIXME: only happens when 'all' is imported lol
26
27
  _register_conditional_import('..marshal', '.marshal', __package__)
omlish/sql/__init__.py CHANGED
@@ -5,9 +5,9 @@ from .. import lang as _lang
5
5
 
6
6
 
7
7
  if _ta.TYPE_CHECKING:
8
- from . import api
8
+ from . import api # noqa
9
9
  else:
10
- api = _lang.proxy_import('.api', __package__)
10
+ globals()['api'] = _lang.proxy_import('.api', __package__)
11
11
 
12
12
  from .dbs import ( # noqa
13
13
  DbLoc,
@@ -24,6 +24,6 @@ from .qualifiedname import ( # noqa
24
24
  )
25
25
 
26
26
  if _ta.TYPE_CHECKING:
27
- from . import queries
27
+ from . import queries # noqa
28
28
  else:
29
- queries = _lang.proxy_import('.queries', __package__)
29
+ globals()['queries'] = _lang.proxy_import('.queries', __package__)
@@ -25,10 +25,15 @@ class SqlalchemyApiWrapper(api.ContextCloser, ta.Generic[T]):
25
25
  self._u = u
26
26
  self._auto_close = auto_close
27
27
 
28
- def close(self) -> None:
28
+ @property
29
+ @ta.override
30
+ def _is_resourceless(self) -> bool:
31
+ return not self._auto_close
32
+
33
+ def _close(self) -> None:
29
34
  if self._auto_close and hasattr(self._u, 'close'):
30
35
  self._u.close()
31
- super().close()
36
+ super()._close()
32
37
 
33
38
 
34
39
  ##
@@ -1,7 +1,10 @@
1
- from .base import ( # noqa
2
- Closer,
3
- ContextCloser,
1
+ from .asquery import ( # noqa
2
+ AsQueryParams,
3
+ as_query,
4
+ as_query_,
5
+ )
4
6
 
7
+ from .base import ( # noqa
5
8
  Querier,
6
9
  Rows,
7
10
  Conn,
@@ -33,6 +36,7 @@ from .errors import ( # noqa
33
36
 
34
37
  from .funcs import ( # noqa
35
38
  query,
39
+ query_all,
36
40
  exec, # noqa
37
41
  )
38
42
 
@@ -41,6 +45,25 @@ from .queries import ( # noqa
41
45
  Query,
42
46
  )
43
47
 
48
+ from .resources import ( # noqa
49
+ get_resource_debug,
50
+ set_resource_debug,
51
+
52
+ UnclosedResourceWarning,
53
+ Closer,
54
+
55
+ ResourceNotEnteredError,
56
+ ContextCloser,
57
+ )
58
+
44
59
  from .rows import ( # noqa
45
60
  Row,
46
61
  )
62
+
63
+
64
+ ##
65
+
66
+
67
+ from ...lang.imports import _register_conditional_import # noqa
68
+
69
+ _register_conditional_import('..queries', '._queries', __package__)
@@ -0,0 +1,32 @@
1
+ """
2
+ TODO:
3
+ - dialect lol
4
+ - args lol
5
+ """
6
+ from ..queries import Stmt
7
+ from ..queries.rendering import render
8
+ from .asquery import AsQueryParams
9
+ from .asquery import as_query_
10
+ from .queries import Query
11
+ from .queries import QueryMode
12
+
13
+
14
+ ##
15
+
16
+
17
+ @as_query_.register
18
+ def _(
19
+ stmt: Stmt,
20
+ *,
21
+ params: AsQueryParams,
22
+ ) -> Query:
23
+ rq = render(stmt)
24
+
25
+ if rq.args:
26
+ raise NotImplementedError
27
+
28
+ return Query(
29
+ mode=QueryMode.of(params.mode, QueryMode.QUERY),
30
+ text=rq.s,
31
+ args=[],
32
+ )
@@ -0,0 +1,67 @@
1
+ import dataclasses as dc
2
+ import functools
3
+ import typing as ta
4
+
5
+ from ... import check
6
+ from .base import Querier
7
+ from .queries import Query
8
+ from .queries import QueryMode
9
+
10
+
11
+ ##
12
+
13
+
14
+ @dc.dataclass(frozen=True, kw_only=True)
15
+ class AsQueryParams:
16
+ mode: QueryMode | str | None = None
17
+ querier: Querier | None = None
18
+
19
+
20
+ def as_query(
21
+ obj: ta.Any,
22
+ *args: ta.Any,
23
+ mode: QueryMode | str | None = None,
24
+ querier: Querier | None = None,
25
+ ) -> Query:
26
+ return as_query_(
27
+ obj,
28
+ *args,
29
+ params=AsQueryParams(
30
+ mode=mode,
31
+ querier=querier,
32
+ ),
33
+ )
34
+
35
+
36
+ @functools.singledispatch
37
+ def as_query_(
38
+ obj: ta.Any,
39
+ *args: ta.Any,
40
+ params: AsQueryParams,
41
+ ) -> Query:
42
+ raise TypeError(obj)
43
+
44
+
45
+ @as_query_.register
46
+ def _(
47
+ q: Query,
48
+ *,
49
+ params: AsQueryParams,
50
+ ) -> Query:
51
+ if params.mode is not None:
52
+ check.arg(q.mode is QueryMode.of(params.mode))
53
+
54
+ return q
55
+
56
+
57
+ @as_query_.register
58
+ def _(
59
+ s: str,
60
+ *args: ta.Any,
61
+ params: AsQueryParams,
62
+ ) -> Query:
63
+ return Query(
64
+ mode=QueryMode.of(params.mode, QueryMode.QUERY),
65
+ text=s,
66
+ args=args,
67
+ )
omlish/sql/api/base.py CHANGED
@@ -9,29 +9,13 @@ from ... import lang
9
9
  from .columns import Column
10
10
  from .columns import Columns
11
11
  from .queries import Query
12
+ from .resources import ContextCloser
12
13
  from .rows import Row
13
14
 
14
15
 
15
16
  ##
16
17
 
17
18
 
18
- class Closer(lang.Abstract):
19
- def close(self) -> None:
20
- pass
21
-
22
-
23
- class ContextCloser(Closer):
24
- def __enter__(self) -> ta.Self:
25
- return self
26
-
27
- @ta.final
28
- def __exit__(self, exc_type, exc_val, exc_tb):
29
- self.close()
30
-
31
-
32
- ##
33
-
34
-
35
19
  class Querier(ContextCloser, lang.Abstract):
36
20
  @property
37
21
  @abc.abstractmethod
omlish/sql/api/dbapi.py CHANGED
@@ -41,11 +41,16 @@ class DbapiRows(Rows):
41
41
  self._cursor = cursor
42
42
  self._columns = columns
43
43
 
44
+ def _close(self) -> None:
45
+ self._cursor.close()
46
+ super()._close()
47
+
44
48
  @property
45
49
  def columns(self) -> Columns:
46
50
  return self._columns
47
51
 
48
52
  def __next__(self) -> Row:
53
+ self._check_entered()
49
54
  values = self._cursor.fetchone()
50
55
  if values is None:
51
56
  raise StopIteration
@@ -58,11 +63,16 @@ class DbapiConn(Conn):
58
63
 
59
64
  self._conn = conn
60
65
 
66
+ def _close(self) -> None:
67
+ self._conn.close()
68
+ super()._close()
69
+
61
70
  @property
62
71
  def adapter(self) -> Adapter:
63
72
  raise NotImplementedError
64
73
 
65
74
  def query(self, query: Query) -> Rows:
75
+ self._check_entered()
66
76
  cursor = self._conn.cursor()
67
77
  try:
68
78
  cursor.execute(query.text)
@@ -73,9 +83,6 @@ class DbapiConn(Conn):
73
83
  cursor.close()
74
84
  raise
75
85
 
76
- def close(self) -> None:
77
- self._conn.close()
78
-
79
86
 
80
87
  class DbapiDb(Db):
81
88
  def __init__(
@@ -92,6 +99,7 @@ class DbapiDb(Db):
92
99
  self._adapter = adapter
93
100
 
94
101
  def connect(self) -> Conn:
102
+ self._check_entered()
95
103
  dbapi_conn = self._conn_fac()
96
104
  return DbapiConn(dbapi_conn)
97
105
 
omlish/sql/api/funcs.py CHANGED
@@ -1,73 +1,56 @@
1
1
  import typing as ta
2
2
 
3
+ from .asquery import as_query
3
4
  from .base import Querier
4
5
  from .base import Rows
5
- from .queries import Query
6
6
  from .queries import QueryMode
7
+ from .rows import Row
7
8
 
8
9
 
9
10
  ##
10
11
 
11
12
 
12
- @ta.overload
13
13
  def query(
14
14
  querier: Querier,
15
- query: Query, # noqa
16
- ) -> Rows:
17
- ...
18
-
19
-
20
- @ta.overload
21
- def query(
22
- querier: Querier,
23
- text: str,
15
+ obj: ta.Any,
24
16
  *args: ta.Any,
25
17
  ) -> Rows:
26
- ...
27
-
28
-
29
- def query(
30
- querier,
18
+ q = as_query(
31
19
  obj,
32
20
  *args,
33
- ):
34
- if isinstance(obj, Query):
35
- q = obj
36
- else:
37
- q = Query.of(obj, *args, mode=QueryMode.QUERY)
21
+ mode=QueryMode.QUERY,
22
+ querier=querier,
23
+ )
38
24
 
39
25
  return querier.query(q)
40
26
 
41
27
 
42
- ##
28
+ #
43
29
 
44
30
 
45
- @ta.overload
46
- def exec( # noqa
31
+ def query_all(
47
32
  querier: Querier,
48
- query: Query, # noqa
49
- ) -> None:
50
- ...
33
+ obj: ta.Any,
34
+ *args: ta.Any,
35
+ ) -> list[Row]:
36
+ with query(querier, obj, *args) as rows:
37
+ return list(rows)
38
+
39
+
40
+ ##
51
41
 
52
42
 
53
- @ta.overload
54
43
  def exec( # noqa
55
44
  querier: Querier,
56
- text: str,
45
+ obj: ta.Any,
57
46
  *args: ta.Any,
58
47
  ) -> None:
59
- ...
60
-
61
-
62
- def exec( # noqa
63
- querier,
64
- obj,
65
- *args,
66
- ):
67
- if isinstance(obj, Query):
68
- q = obj
69
- else:
70
- q = Query.of(obj, *args, mode=QueryMode.EXEC)
48
+ q = as_query(
49
+ obj,
50
+ *args,
51
+ mode=QueryMode.EXEC,
52
+ querier=querier,
53
+ )
71
54
 
72
55
  with querier.query(q):
73
56
  pass
omlish/sql/api/queries.py CHANGED
@@ -13,51 +13,24 @@ class QueryMode(enum.Enum):
13
13
  QUERY = enum.auto()
14
14
  EXEC = enum.auto()
15
15
 
16
+ @classmethod
17
+ def of(
18
+ cls,
19
+ o: ta.Union[str, 'QueryMode', None],
20
+ default: ta.Optional['QueryMode'] = None,
21
+ ) -> 'QueryMode':
22
+ if o is None:
23
+ return check.not_none(check.isinstance(default, cls))
24
+ elif isinstance(o, str):
25
+ return cls[o.upper()] # noqa
26
+ elif isinstance(o, cls):
27
+ return o
28
+ else:
29
+ raise TypeError(o)
30
+
16
31
 
17
32
  @dc.dataclass(frozen=True)
18
33
  class Query(lang.Final):
19
34
  mode: QueryMode
20
35
  text: str
21
36
  args: ta.Sequence[ta.Any]
22
-
23
- #
24
-
25
- @classmethod
26
- @ta.overload
27
- def of(
28
- cls,
29
- query: 'Query',
30
- ) -> 'Query':
31
- ...
32
-
33
- @classmethod
34
- @ta.overload
35
- def of(
36
- cls,
37
- text: str,
38
- *args: ta.Any,
39
- mode: str | QueryMode = QueryMode.QUERY,
40
- ) -> 'Query':
41
- ...
42
-
43
- @classmethod # type: ignore[misc]
44
- def of(cls, obj, *args, **kwargs):
45
- if isinstance(obj, Query):
46
- check.arg(not args)
47
- check.arg(not kwargs)
48
- return obj
49
-
50
- elif isinstance(obj, str):
51
- mode = kwargs.pop('mode', QueryMode.QUERY)
52
- if isinstance(mode, str):
53
- mode = QueryMode[mode.upper()]
54
- check.arg(not kwargs)
55
-
56
- return cls(
57
- mode=mode,
58
- text=obj,
59
- args=args,
60
- )
61
-
62
- else:
63
- raise TypeError(obj)
@@ -0,0 +1,106 @@
1
+ import traceback
2
+ import typing as ta
3
+ import warnings
4
+
5
+ from ... import lang
6
+
7
+
8
+ ##
9
+
10
+
11
+ DEBUG = __debug__
12
+
13
+
14
+ def get_resource_debug() -> bool:
15
+ return DEBUG
16
+
17
+
18
+ def set_resource_debug(debug: bool) -> None:
19
+ global DEBUG
20
+ DEBUG = debug
21
+
22
+
23
+ ##
24
+
25
+
26
+ class UnclosedResourceWarning(Warning):
27
+ pass
28
+
29
+
30
+ class Closer(lang.Abstract):
31
+ def __init__(self, *args: ta.Any, **kwargs: ta.Any) -> None:
32
+ super().__init__(*args, **kwargs)
33
+
34
+ self.__closed = False
35
+
36
+ self.__debug = DEBUG
37
+ if self.__debug:
38
+ self.__repr = repr(self)
39
+ self.__traceback = traceback.format_stack()[:-1]
40
+
41
+ @property
42
+ def _is_resourceless(self) -> bool:
43
+ return False
44
+
45
+ @ta.final
46
+ def close(self) -> None:
47
+ self.__closed = True
48
+ self._close()
49
+
50
+ def _close(self) -> None:
51
+ pass
52
+
53
+ def __del__(self) -> None:
54
+ if (
55
+ not self._is_resourceless and
56
+ self.__debug and
57
+ not self.__closed
58
+ ):
59
+ warnings.warn(
60
+ f'\n\n{(sep := ("=" * 40))}\n'
61
+ f'{self.__class__.__name__} object {self.__repr} '
62
+ f'was not properly closed before deletion. Please ensure that `close()` is called before the object is '
63
+ f'deleted.'
64
+ f'\n\n'
65
+ f'{"".join(self.__traceback).rstrip()}'
66
+ f'\n{sep}\n',
67
+ UnclosedResourceWarning,
68
+ )
69
+
70
+
71
+ ##
72
+
73
+
74
+ class ResourceNotEnteredError(Exception):
75
+ pass
76
+
77
+
78
+ class ContextCloser(Closer):
79
+ def __init__(self, *args: ta.Any, **kwargs: ta.Any) -> None:
80
+ super().__init__(*args, **kwargs)
81
+
82
+ self.__entered = False
83
+
84
+ @ta.final
85
+ def __enter__(self) -> ta.Self:
86
+ self.__entered = True
87
+ self._enter()
88
+ return self
89
+
90
+ def _enter(self) -> None:
91
+ pass
92
+
93
+ def _is_entered(self) -> bool:
94
+ return self.__entered
95
+
96
+ def _check_entered(self) -> None:
97
+ if not self.__entered:
98
+ try:
99
+ raise ResourceNotEnteredError(self) # noqa
100
+ except Exception:
101
+ self.close()
102
+ raise
103
+
104
+ @ta.final
105
+ def __exit__(self, exc_type, exc_val, exc_tb):
106
+ self.close()
omlish/sql/api/rows.py CHANGED
@@ -33,7 +33,7 @@ class Row(lang.Final, ta.Generic[T]):
33
33
  def __contains__(self, item: str | int) -> bool:
34
34
  raise TypeError('Row.__contains__ is ambiguous - use .columns.__contains__ or .values.__contains__')
35
35
 
36
- def __getitem__(self, item) -> T:
36
+ def __getitem__(self, item: str | int) -> T:
37
37
  if isinstance(item, str):
38
38
  return self.values[self.columns.index(item)]
39
39
  elif isinstance(item, int):
@@ -46,3 +46,6 @@ class Row(lang.Final, ta.Generic[T]):
46
46
  return self.values[idx]
47
47
  else:
48
48
  return None
49
+
50
+ def to_dict(self) -> dict[str, ta.Any]:
51
+ return {c.name: v for c, v in self}
@@ -107,3 +107,11 @@ Q = StdBuilder()
107
107
  from ...lang.imports import _register_conditional_import # noqa
108
108
 
109
109
  _register_conditional_import('...marshal', '.marshal', __package__)
110
+
111
+
112
+ ##
113
+
114
+
115
+ from ...lang.imports import _trigger_conditional_imports # noqa
116
+
117
+ _trigger_conditional_imports(__package__)
@@ -26,6 +26,9 @@ from .unary import UnaryOp
26
26
  from .unary import UnaryOps
27
27
 
28
28
 
29
+ ##
30
+
31
+
29
32
  @dc.dataclass(frozen=True)
30
33
  class OpMarshalerUnmarshaler(msh.Marshaler, msh.Unmarshaler):
31
34
  ty: type
omlish/sql/queries/ops.py CHANGED
@@ -1,6 +1,9 @@
1
1
  import enum
2
2
 
3
3
 
4
+ ##
5
+
6
+
4
7
  class OpKind(enum.Enum):
5
8
  CMP = enum.auto()
6
9
  ARITH = enum.auto()
@@ -48,6 +48,9 @@ from .unary import UnaryOp
48
48
  from .unary import UnaryOps
49
49
 
50
50
 
51
+ ##
52
+
53
+
51
54
  @dc.dataclass(frozen=True)
52
55
  class RenderedQueryParts(lang.Final):
53
56
  p: tp.Part
omlish/sql/queries/std.py CHANGED
@@ -12,6 +12,9 @@ from .stmts import StmtBuilder
12
12
  from .unary import UnaryBuilder
13
13
 
14
14
 
15
+ ##
16
+
17
+
15
18
  class StdBuilder(
16
19
  InsertBuilder,
17
20
  SelectBuilder,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev297
3
+ Version: 0.0.0.dev299
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=pjGUyLHaoWpPqRP3jz2u1fC1qoRc2lvrEcpU_Ax2tdg,8253
2
- omlish/__about__.py,sha256=njktGXItvJUlAo47q_VkLF-Re3G-ca4oRUL7K6mtQtM,3478
2
+ omlish/__about__.py,sha256=tghPJ3r3hoOBraig8kr81p5Jv_kgJPAvrhVaVK8Li7o,3478
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=rer-TPOFDU6fYq_AWio_AmA-ckZ8JDY5shIzQ_yXfzA,8414
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -87,7 +87,7 @@ omlish/antlr/_runtime/xpath/XPathLexer.py,sha256=WvGKQjQnu7pX5C4CFKtsCzba2B2W6ie
87
87
  omlish/antlr/_runtime/xpath/__init__.py,sha256=lMd_BbXYdlDhZQN_q0TKN978XW5G0pq618F0NaLkpFE,71
88
88
  omlish/argparse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
89
  omlish/argparse/all.py,sha256=NeeMM5MIebY7XDAHaCxUzeesEoUYwsf5i9PrBUcO1cI,1057
90
- omlish/argparse/cli.py,sha256=vVLlhJPt0PKaNfIBrXTzz9cHyy2dFEY8hlQ3GvtKbwc,8704
90
+ omlish/argparse/cli.py,sha256=KftfiN0fBOdybCWoTW4l967r8OrXe_WtjOQWARcHTv0,8746
91
91
  omlish/asyncs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
92
  omlish/asyncs/all.py,sha256=MjW0P9K8XBrw6AaH2X_qD5Y7hEZOF0cktqFv5BDGH-k,649
93
93
  omlish/asyncs/bridge.py,sha256=oFCqwGY9u9JYB-tee7GS0gjtIFp19rdZD2Z0YPRjj9k,9738
@@ -473,7 +473,7 @@ omlish/lang/contextmanagers.py,sha256=pN8X4ZCagqU9_xWumi8gZPdMIWlInA-_zQrkl7o5VP
473
473
  omlish/lang/datetimes.py,sha256=mrTtA67JYpfQwSlzdPcBtvm6dAyYM_dXNnlxFwFQH0M,228
474
474
  omlish/lang/descriptors.py,sha256=zBtgO9LjdSTGHNUgiIqswh78WOVoGH6KzS0NbgB1Wls,6572
475
475
  omlish/lang/enums.py,sha256=F9tflHfaAoV2MpyuhZzpfX9-H55M3zNa9hCszsngEo8,111
476
- omlish/lang/functions.py,sha256=bg2IxTFmd_J22qF3XWIRBvSIpLwPRiH_KxGXcm0QVrc,5944
476
+ omlish/lang/functions.py,sha256=51CoKtH_-CXUsKvtCexaR3OLZOtIwSdv4f4DtGBZdpA,6029
477
477
  omlish/lang/generators.py,sha256=5tbjVAywiZH6oAdj1sJLRMtIkC9y3rAkecLT7Z3m7_g,5251
478
478
  omlish/lang/imports.py,sha256=aC1u2eTrxHhhxShKbJvXswe3aJ7K76vT4YK8LrsvRWU,10476
479
479
  omlish/lang/iterables.py,sha256=HOjcxOwyI5bBApDLsxRAGGhTTmw7fdZl2kEckxRVl-0,1994
@@ -626,7 +626,7 @@ omlish/reflect/ops.py,sha256=RJ6jzrM4ieFsXzWyNXWV43O_WgzEaUvlHSc5N2ezW2A,2044
626
626
  omlish/reflect/subst.py,sha256=g3q7NmNWsmc67mcchmCE3WFPCMDSBq-FXn4ah-DWL_U,3622
627
627
  omlish/reflect/types.py,sha256=Cn9FYGoiCNt0FS0YLiTTAR12WKcesWMapCrVYcb8IDo,9225
628
628
  omlish/secrets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
629
- omlish/secrets/all.py,sha256=kUTuS4pZVskJe1kFN6m1F1br09BNSjX7MUC2RZRndwc,437
629
+ omlish/secrets/all.py,sha256=gv_d9SfyMxso30HsrSz9XmIrSZOdl3rLA5MSH0ZXfgM,486
630
630
  omlish/secrets/crypto.py,sha256=9D21lnvPhStwu8arD4ssT0ih0bDG-nlqIRdVgYL40xA,3708
631
631
  omlish/secrets/marshal.py,sha256=u90n1OfRfdpH1T2F0xK_pAPH1ENYL6acFt6XdVd3KvI,1986
632
632
  omlish/secrets/openssl.py,sha256=UT_dXJ4zA1s9e-UHoW_NLGHQO7iouUNPnJNkkpuw3JI,6213
@@ -720,27 +720,30 @@ omlish/specs/proto/_antlr/Protobuf3Listener.py,sha256=hjzAJjcj4xWRim-68v-6QwIsPV
720
720
  omlish/specs/proto/_antlr/Protobuf3Parser.py,sha256=VmkUyJx3WxIgAecOa1BGwbO9fVNysZt5-arQ-wDubpk,132411
721
721
  omlish/specs/proto/_antlr/Protobuf3Visitor.py,sha256=zEVBXly2k9Cqmgdb45QwpLR-fZCEq8hpp2WQj-s7Wps,8782
722
722
  omlish/specs/proto/_antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
723
- omlish/sql/__init__.py,sha256=AFcSRUcz9sYMqlOsv8oZWai3Oi1PLygJbZ2YSzWUvhc,459
723
+ omlish/sql/__init__.py,sha256=DXK3EjPKXKS0WUV-bIVtzH0GsmOqCYrNLFkvDJGCORM,501
724
724
  omlish/sql/abc.py,sha256=3hrCjB4jnPVMef_YXClCblzYUZ9l9yaxJJdd5_Nu9GM,4043
725
725
  omlish/sql/dbapi.py,sha256=DfMxCyltpMj6hUiLti1omUvJyMGbrkGxcz2ywolOpPA,2979
726
726
  omlish/sql/dbs.py,sha256=65e388987upJpsFX8bNL7uhiYv2sCsmk9Y04V0MXdsI,1873
727
727
  omlish/sql/params.py,sha256=Z4VPet6GhNqD1T_MXSWSHkdy3cpUEhST-OplC4B_fYI,4433
728
728
  omlish/sql/qualifiedname.py,sha256=c3GQzxh9sNyE_TP32PnlCun_F2bKXvX1ohtt6esTsjo,2269
729
729
  omlish/sql/alchemy/__init__.py,sha256=mZiu0F4Y_5qQpl-xz4xnb0feVGZTDp3I4R6k7SVY_7M,760
730
- omlish/sql/alchemy/apiadapter.py,sha256=DnyCDl2mWbiZPwQ6RAxxFgfMCoVJqQ3Nzut-INhz9x8,2586
730
+ omlish/sql/alchemy/apiadapter.py,sha256=QrkvlzqMl_S2nxOPQ8-g1UaWRSTZNna1-8XouOn8xdY,2696
731
731
  omlish/sql/alchemy/asyncs.py,sha256=MwZwWIaZsUCQLcTA8mdHUPZmR-pXEVSAsvd15FCm3W4,3692
732
732
  omlish/sql/alchemy/duckdb.py,sha256=kr7pIhiBLNAuZrcigHDtFg9zHkVcrRW3LfryO9VJ4mk,3749
733
733
  omlish/sql/alchemy/exprs.py,sha256=gO4Fj4xEY-PuDgV-N8hBMy55glZz7O-4H7v1LWabfZY,323
734
734
  omlish/sql/alchemy/secrets.py,sha256=WEeaec1ejQcE3Yaa7p5BSP9AMGEzy1lwr7QMSRL0VBw,180
735
735
  omlish/sql/alchemy/sqlean.py,sha256=RbkuOuFIfM4fowwKk8-sQ6Dxk-tTUwxS94nY5Kxt52s,403
736
- omlish/sql/api/__init__.py,sha256=QmNO4EpT0_xiemhA5u55GHoH17j0k7ezyO_lEyjs34M,570
737
- omlish/sql/api/base.py,sha256=-AePkKy4uxYuob2J4GEwsSvtbFyvNIunNyE3u7p1Uas,1529
736
+ omlish/sql/api/__init__.py,sha256=Ee-DgQPo_fUqlYL3NBzk6kmj_cXlnZIua5jk85UHWHI,951
737
+ omlish/sql/api/_queries.py,sha256=FqIrtU6JdzQD4S4zv9tdDuzCLHSgJjK8WSfT7Ag4umI,530
738
+ omlish/sql/api/asquery.py,sha256=8eBoJyyu0kHW3k3yytEcT-B6UAI_slKB0QtSK_WQS7g,1203
739
+ omlish/sql/api/base.py,sha256=E_t54OFr0BX604vOfQZGxh_n6EdOBF2Tvnrg25dMKXo,1314
738
740
  omlish/sql/api/columns.py,sha256=UBol4bfwZ1nhcjv2gE1JhUMzRFeqtiCDo2T9CUGYb64,1943
739
- omlish/sql/api/dbapi.py,sha256=H3bFoWI-ox81APX3xBbjylNWyMUXh78ICMQjRrlDNxw,2426
741
+ omlish/sql/api/dbapi.py,sha256=bDVqmljmLMdurMhIy3vx-dJvK1KiZ7XBhZ2Zx6W9aBs,2627
740
742
  omlish/sql/api/errors.py,sha256=YtC2gz5DqRTT3uCJniUOufVH1GEnFIc5ElkYLK3BHwM,230
741
- omlish/sql/api/funcs.py,sha256=-H6V-o9JPSHFXsxdHtutB4mP2LwJfCzlLbRrPHunmB4,990
742
- omlish/sql/api/queries.py,sha256=IgB8_sDe40-mKE-ByTmZ4GVOCdLLJDzJGJCevMd8R5s,1207
743
- omlish/sql/api/rows.py,sha256=MEK9LNYEe8vLEJXQJD63MpnSOiE22cawJL-dUWQD6sU,1246
743
+ omlish/sql/api/funcs.py,sha256=kOMMzODkJHyKVmGKFS-6GIgil5I6ha1qjqA3IecgCvI,819
744
+ omlish/sql/api/queries.py,sha256=OVsVqNyXXJQVDPfV3GFE2gwnHyGEenS65rTQRTNGx1Y,735
745
+ omlish/sql/api/resources.py,sha256=DTVQmKjhaLi27jHWYkF20VhwGvIazZWxyKzF0Wn9-dc,2228
746
+ omlish/sql/api/rows.py,sha256=Jo3AA_6Wt7tlwLO6-rp0arzYFqZXSxPudGPkW2xCYgQ,1346
744
747
  omlish/sql/parsing/Minisql.g4,sha256=Jw8xT-8UI6ySHAgStyCg5QX9NTCinvTenLJReWiZIJU,4578
745
748
  omlish/sql/parsing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
746
749
  omlish/sql/parsing/parsing.py,sha256=SIbrAkWCgx_ekBOzBGc0eC_HfW--ciAtU_-Vqmyy6vw,3347
@@ -749,21 +752,21 @@ omlish/sql/parsing/_antlr/MinisqlListener.py,sha256=2py_bfDQeEtJaJh9rtpKghbSrQlE
749
752
  omlish/sql/parsing/_antlr/MinisqlParser.py,sha256=y9SFjXdQlWYJa2PbPm30d5SfcYM_8M8ts46IHhENbNc,132457
750
753
  omlish/sql/parsing/_antlr/MinisqlVisitor.py,sha256=NCPorucLLOZ-Q99BtNbDOAfHytQl8wyroR8pI1uVovg,10030
751
754
  omlish/sql/parsing/_antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
752
- omlish/sql/queries/__init__.py,sha256=2Wb05RFCKYZR3wO5YM60txNgjiDLJMYXC4gKAIUSsmc,1415
755
+ omlish/sql/queries/__init__.py,sha256=LpBnJOGoT5Dw2C043yo1XXIg0C_eHda-u6DR2ZAKT7c,1530
753
756
  omlish/sql/queries/base.py,sha256=pQ6p8dSsHwsWa-lmK2h8RY2UJ1mwJRhByOgrCIW3dBs,3229
754
757
  omlish/sql/queries/binary.py,sha256=dcEzeEn104AMPuQ7QrJU2O-YCN3SUdxB5S4jaWKOUqY,2253
755
758
  omlish/sql/queries/exprs.py,sha256=dG9L218QtJM1HtDYIMWqHimK03N6AL1WONk3FvVRcXY,1480
756
759
  omlish/sql/queries/idents.py,sha256=w2RxO6SR3K-u30S259OtnAZaPv7YA70PzY9R7RtuCQ8,891
757
760
  omlish/sql/queries/inserts.py,sha256=pSQXDSR1oDUmxjeIYuSbxpAZXvYQ-EJF6a62ON5Un-k,1299
758
- omlish/sql/queries/marshal.py,sha256=TA-wFmLqiK6fhIYwew-9oKa_dfFaIXwNMIE05WVwDd0,3011
761
+ omlish/sql/queries/marshal.py,sha256=yVfN5VgYMYDaYTE6FZ8Sea7GrRobn40Hc8kogrfKmjE,3016
759
762
  omlish/sql/queries/multi.py,sha256=7x6x-4jnPzxA6ZasBjnjFuhHFpWt5rGCua3UvuTMIJ0,837
760
763
  omlish/sql/queries/names.py,sha256=4sDvgRobMEt_6mDeuYVbCqHzLCOwpXUdEyyB4-QjxKo,1996
761
- omlish/sql/queries/ops.py,sha256=B7IDfjr2DW5LJhWoNaY1WW90BJhe5ZtmxIELhWXbW-0,129
764
+ omlish/sql/queries/ops.py,sha256=pDZ_2Jo_Fa8DDbtYkc6-9eehkWsZPI-jh-KFlubcY6Y,134
762
765
  omlish/sql/queries/params.py,sha256=FXgZO6F_fmRQb9CVo4PkRoypm_fSB_AB_JoM3PxRkKM,1206
763
766
  omlish/sql/queries/relations.py,sha256=7YrEC9IjoVpRGLAFKRSRsHHnTmx-g7hBNXsOgP2HOuI,2998
764
- omlish/sql/queries/rendering.py,sha256=XaNpZY0itHBxT-rWeUtGb0Rg1T4dKaUdCdFC2I-LRq4,7657
767
+ omlish/sql/queries/rendering.py,sha256=iEQGVP1nOhaZy9FYNwKkOUgqFH0pxfvsCsJpHX8E9Vw,7662
765
768
  omlish/sql/queries/selects.py,sha256=5CD4qmlv5hysQKmoZuF1bbikA-VcC9opN94Ea1QE3mU,1577
766
- omlish/sql/queries/std.py,sha256=J2ZDfDyLzRm8q5-TLAN6I_qjhs-7RpfW23yuCYYLf5k,643
769
+ omlish/sql/queries/std.py,sha256=7kF76kq_b6Qaki-lYiBlZiZmtpWYqRqAcLU8x-bBZn0,648
767
770
  omlish/sql/queries/stmts.py,sha256=pBqwD7dRlqMu6uh6vR3xaWOEgbZCcFWbOQ9ryYd17T4,441
768
771
  omlish/sql/queries/unary.py,sha256=MEYBDZn_H0bexmUrJeONOv5-gIpYowUaXOsEHeQM4ks,1144
769
772
  omlish/sql/tabledefs/__init__.py,sha256=TvtQsp-jJu6_ZahyCOFAaElSSBcRftNyJpdiDPGYCDk,190
@@ -840,9 +843,9 @@ omlish/typedvalues/holder.py,sha256=ZTnHiw-K38ciOBLEdwgrltr7Xp8jjEs_0Lp69DH-G-o,
840
843
  omlish/typedvalues/marshal.py,sha256=hWHRLcrGav7lvXJDtb9bNI0ickl4SKPQ6F4BbTpqw3A,4219
841
844
  omlish/typedvalues/reflect.py,sha256=Ih1YgU-srUjsvBn_P7C66f73_VCvcwqE3ffeBnZBgt4,674
842
845
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
843
- omlish-0.0.0.dev297.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
844
- omlish-0.0.0.dev297.dist-info/METADATA,sha256=bH7FMyIVFXinvhjrOVckLE2J0ToLGMIdaH-8HXxM3jU,4416
845
- omlish-0.0.0.dev297.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
846
- omlish-0.0.0.dev297.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
847
- omlish-0.0.0.dev297.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
848
- omlish-0.0.0.dev297.dist-info/RECORD,,
846
+ omlish-0.0.0.dev299.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
847
+ omlish-0.0.0.dev299.dist-info/METADATA,sha256=T9HA9WB2SuPxxk-DiWerqiu1KkDizRIPRBitUe0csao,4416
848
+ omlish-0.0.0.dev299.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
849
+ omlish-0.0.0.dev299.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
850
+ omlish-0.0.0.dev299.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
851
+ omlish-0.0.0.dev299.dist-info/RECORD,,