pyoq-sql 1.0.2__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.
- pyoq/__init__.py +10 -0
- pyoq/__main__.py +5 -0
- pyoq/_native.pyi +5 -0
- pyoq/cli/__init__.py +5 -0
- pyoq/cli/commands.py +270 -0
- pyoq/cli/defaults.py +98 -0
- pyoq/cli/services.py +97 -0
- pyoq/config/__init__.py +31 -0
- pyoq/config/connection.py +161 -0
- pyoq/config/loader.py +289 -0
- pyoq/config/models.py +245 -0
- pyoq/config/values.py +142 -0
- pyoq/descriptors.py +165 -0
- pyoq/diagnostics/__init__.py +68 -0
- pyoq/diagnostics/budget.py +136 -0
- pyoq/diagnostics/events.py +137 -0
- pyoq/diagnostics/fingerprint.py +267 -0
- pyoq/diagnostics/instrumented.py +237 -0
- pyoq/diagnostics/metrics.py +61 -0
- pyoq/diagnostics/observation.py +227 -0
- pyoq/diagnostics/scoped.py +103 -0
- pyoq/django/__init__.py +15 -0
- pyoq/django/apps.py +17 -0
- pyoq/django/execution.py +317 -0
- pyoq/django/generation.py +59 -0
- pyoq/django/management/__init__.py +0 -0
- pyoq/django/management/commands/__init__.py +0 -0
- pyoq/django/management/commands/makemigrations.py +53 -0
- pyoq/django/management/commands/pyoq_codegen.py +75 -0
- pyoq/django/parameters.py +101 -0
- pyoq/django/schema.py +379 -0
- pyoq/django/settings.py +87 -0
- pyoq/django/timeouts.py +105 -0
- pyoq/dsl/__init__.py +64 -0
- pyoq/dsl/aio/__init__.py +31 -0
- pyoq/dsl/aio/context.py +295 -0
- pyoq/dsl/aio/queries.py +335 -0
- pyoq/dsl/aio/writes.py +368 -0
- pyoq/dsl/context.py +326 -0
- pyoq/dsl/entry.py +37 -0
- pyoq/dsl/labels.py +36 -0
- pyoq/dsl/queries.py +339 -0
- pyoq/dsl/result.py +164 -0
- pyoq/dsl/writes.py +360 -0
- pyoq/errors.py +317 -0
- pyoq/fastapi/__init__.py +32 -0
- pyoq/fastapi/dependencies.py +167 -0
- pyoq/fastapi/lifespan.py +119 -0
- pyoq/fetching/__init__.py +55 -0
- pyoq/fetching/collections.py +136 -0
- pyoq/fetching/execution.py +587 -0
- pyoq/fetching/joined.py +79 -0
- pyoq/fetching/nesting.py +183 -0
- pyoq/fetching/plans.py +541 -0
- pyoq/fetching/select_in.py +149 -0
- pyoq/fetching/tables.py +110 -0
- pyoq/generation/__init__.py +54 -0
- pyoq/generation/cleanup.py +44 -0
- pyoq/generation/contracts.py +248 -0
- pyoq/generation/drift.py +169 -0
- pyoq/generation/lock.py +33 -0
- pyoq/generation/manifest.py +114 -0
- pyoq/generation/model.py +1001 -0
- pyoq/generation/pipeline.py +119 -0
- pyoq/generation/rendering/__init__.py +5 -0
- pyoq/generation/rendering/domains.py +51 -0
- pyoq/generation/rendering/enums.py +29 -0
- pyoq/generation/rendering/exports.py +70 -0
- pyoq/generation/rendering/imports.py +63 -0
- pyoq/generation/rendering/package.py +56 -0
- pyoq/generation/rendering/relations.py +133 -0
- pyoq/generation/rendering/routines.py +396 -0
- pyoq/generation/rendering/rows.py +79 -0
- pyoq/generation/rendering/source.py +121 -0
- pyoq/generation/rendering/tables.py +300 -0
- pyoq/generation/rendering/writes.py +514 -0
- pyoq/generation/validation.py +27 -0
- pyoq/generation/writer.py +184 -0
- pyoq/hydration/__init__.py +24 -0
- pyoq/hydration/engine.py +155 -0
- pyoq/hydration/identity.py +194 -0
- pyoq/hydration/plan.py +116 -0
- pyoq/migrations/__init__.py +9 -0
- pyoq/migrations/alembic.py +106 -0
- pyoq/migrations/hooks.py +75 -0
- pyoq/naming.py +261 -0
- pyoq/policies/__init__.py +47 -0
- pyoq/policies/bypass.py +122 -0
- pyoq/policies/governed.py +430 -0
- pyoq/policies/model.py +242 -0
- pyoq/policies/rewriting.py +263 -0
- pyoq/py.typed +1 -0
- pyoq/query/__init__.py +312 -0
- pyoq/query/aggregates.py +172 -0
- pyoq/query/arrays.py +65 -0
- pyoq/query/binding.py +52 -0
- pyoq/query/capabilities.py +317 -0
- pyoq/query/casts.py +73 -0
- pyoq/query/choices.py +185 -0
- pyoq/query/decoding.py +360 -0
- pyoq/query/documents.py +56 -0
- pyoq/query/execution/__init__.py +63 -0
- pyoq/query/execution/aio/__init__.py +31 -0
- pyoq/query/execution/aio/operations.py +228 -0
- pyoq/query/execution/aio/pooling.py +233 -0
- pyoq/query/execution/aio/streaming.py +161 -0
- pyoq/query/execution/aio/transactions.py +105 -0
- pyoq/query/execution/batch.py +96 -0
- pyoq/query/execution/binding_style.py +30 -0
- pyoq/query/execution/compilation.py +48 -0
- pyoq/query/execution/context.py +61 -0
- pyoq/query/execution/control.py +50 -0
- pyoq/query/execution/operations.py +224 -0
- pyoq/query/execution/planning.py +107 -0
- pyoq/query/execution/pooling.py +279 -0
- pyoq/query/execution/results.py +36 -0
- pyoq/query/execution/streaming.py +178 -0
- pyoq/query/execution/transactions.py +95 -0
- pyoq/query/expressions.py +1200 -0
- pyoq/query/fields.py +60 -0
- pyoq/query/mysql/__init__.py +59 -0
- pyoq/query/mysql/aio/__init__.py +38 -0
- pyoq/query/mysql/aio/commands.py +389 -0
- pyoq/query/mysql/aio/driver.py +196 -0
- pyoq/query/mysql/aio/executor.py +123 -0
- pyoq/query/mysql/aio/factory.py +26 -0
- pyoq/query/mysql/aio/operations.py +38 -0
- pyoq/query/mysql/aio/pool.py +53 -0
- pyoq/query/mysql/aio/transactions.py +313 -0
- pyoq/query/mysql/commands.py +354 -0
- pyoq/query/mysql/compiler.py +134 -0
- pyoq/query/mysql/context.py +20 -0
- pyoq/query/mysql/executor.py +126 -0
- pyoq/query/mysql/expressions.py +244 -0
- pyoq/query/mysql/factory.py +46 -0
- pyoq/query/mysql/health.py +66 -0
- pyoq/query/mysql/identifiers.py +9 -0
- pyoq/query/mysql/model.py +79 -0
- pyoq/query/mysql/operations.py +43 -0
- pyoq/query/mysql/parameters.py +69 -0
- pyoq/query/mysql/planning.py +20 -0
- pyoq/query/mysql/pool.py +67 -0
- pyoq/query/mysql/transactions.py +331 -0
- pyoq/query/mysql/writes.py +73 -0
- pyoq/query/nodes.py +750 -0
- pyoq/query/postgres/__init__.py +48 -0
- pyoq/query/postgres/aio/__init__.py +25 -0
- pyoq/query/postgres/aio/bulk.py +56 -0
- pyoq/query/postgres/aio/commands.py +264 -0
- pyoq/query/postgres/aio/executor.py +152 -0
- pyoq/query/postgres/aio/factory.py +26 -0
- pyoq/query/postgres/aio/operations.py +26 -0
- pyoq/query/postgres/aio/pool.py +40 -0
- pyoq/query/postgres/aio/transactions.py +295 -0
- pyoq/query/postgres/bulk.py +62 -0
- pyoq/query/postgres/commands.py +238 -0
- pyoq/query/postgres/compiler.py +114 -0
- pyoq/query/postgres/context.py +20 -0
- pyoq/query/postgres/executor.py +147 -0
- pyoq/query/postgres/expressions.py +311 -0
- pyoq/query/postgres/factory.py +24 -0
- pyoq/query/postgres/health.py +24 -0
- pyoq/query/postgres/identifiers.py +9 -0
- pyoq/query/postgres/model.py +81 -0
- pyoq/query/postgres/operations.py +25 -0
- pyoq/query/postgres/parameters.py +71 -0
- pyoq/query/postgres/planning.py +20 -0
- pyoq/query/postgres/pool.py +52 -0
- pyoq/query/postgres/transactions.py +295 -0
- pyoq/query/postgres/writes.py +37 -0
- pyoq/query/projections.py +105 -0
- pyoq/query/raw.py +90 -0
- pyoq/query/recursion.py +265 -0
- pyoq/query/rendering/__init__.py +1 -0
- pyoq/query/rendering/expressions.py +913 -0
- pyoq/query/rendering/identifiers.py +40 -0
- pyoq/query/rendering/projections.py +63 -0
- pyoq/query/rendering/queries.py +334 -0
- pyoq/query/rendering/sources.py +66 -0
- pyoq/query/rendering/writes.py +176 -0
- pyoq/query/results.py +459 -0
- pyoq/query/routines.py +196 -0
- pyoq/query/rows.py +156 -0
- pyoq/query/select.py +793 -0
- pyoq/query/select_nodes.py +277 -0
- pyoq/query/sources.py +236 -0
- pyoq/query/sqlite/__init__.py +43 -0
- pyoq/query/sqlite/commands.py +201 -0
- pyoq/query/sqlite/compiler.py +139 -0
- pyoq/query/sqlite/context.py +20 -0
- pyoq/query/sqlite/executor.py +119 -0
- pyoq/query/sqlite/expressions.py +224 -0
- pyoq/query/sqlite/factory.py +32 -0
- pyoq/query/sqlite/health.py +28 -0
- pyoq/query/sqlite/identifiers.py +9 -0
- pyoq/query/sqlite/model.py +73 -0
- pyoq/query/sqlite/operations.py +36 -0
- pyoq/query/sqlite/parameters.py +50 -0
- pyoq/query/sqlite/planning.py +20 -0
- pyoq/query/sqlite/pool.py +50 -0
- pyoq/query/sqlite/streaming.py +13 -0
- pyoq/query/sqlite/transactions.py +274 -0
- pyoq/query/sqlite/writes.py +35 -0
- pyoq/query/statements.py +27 -0
- pyoq/query/values.py +23 -0
- pyoq/query/vendor.py +162 -0
- pyoq/query/windows.py +424 -0
- pyoq/query/write_nodes.py +174 -0
- pyoq/query/writes.py +628 -0
- pyoq/relations/__init__.py +66 -0
- pyoq/relations/batching.py +219 -0
- pyoq/relations/derivation.py +111 -0
- pyoq/relations/fetching.py +355 -0
- pyoq/relations/graph.py +245 -0
- pyoq/relations/loading.py +74 -0
- pyoq/relations/model.py +75 -0
- pyoq/relations/planning.py +206 -0
- pyoq/runtime/__init__.py +9 -0
- pyoq/runtime/kernels.py +25 -0
- pyoq/runtime/python.py +43 -0
- pyoq/runtime/selection.py +73 -0
- pyoq/sanic/__init__.py +32 -0
- pyoq/sanic/scope.py +197 -0
- pyoq/sanic/workers.py +129 -0
- pyoq/schema/__init__.py +108 -0
- pyoq/schema/codec.py +711 -0
- pyoq/schema/models.py +604 -0
- pyoq/schema/mysql/__init__.py +16 -0
- pyoq/schema/mysql/connection.py +73 -0
- pyoq/schema/mysql/dsn.py +72 -0
- pyoq/schema/mysql/records.py +354 -0
- pyoq/schema/mysql/reflection.py +309 -0
- pyoq/schema/mysql/source.py +30 -0
- pyoq/schema/mysql/sql.py +128 -0
- pyoq/schema/mysql/types.py +105 -0
- pyoq/schema/postgres/__init__.py +13 -0
- pyoq/schema/postgres/connection.py +63 -0
- pyoq/schema/postgres/records.py +384 -0
- pyoq/schema/postgres/reflection.py +466 -0
- pyoq/schema/postgres/source.py +30 -0
- pyoq/schema/postgres/sql.py +246 -0
- pyoq/schema/postgres/types.py +98 -0
- pyoq/schema/registry.py +45 -0
- pyoq/schema/source.py +15 -0
- pyoq/schema/sqlite/__init__.py +6 -0
- pyoq/schema/sqlite/connection.py +54 -0
- pyoq/schema/sqlite/records.py +167 -0
- pyoq/schema/sqlite/reflection.py +393 -0
- pyoq/schema/sqlite/source.py +30 -0
- pyoq/schema/sqlite/sql.py +254 -0
- pyoq/schema/sqlite/types.py +74 -0
- pyoq/serving/__init__.py +23 -0
- pyoq/serving/databases.py +107 -0
- pyoq/serving/opening.py +331 -0
- pyoq/snapshots/__init__.py +20 -0
- pyoq/snapshots/drift.py +312 -0
- pyoq/snapshots/files.py +96 -0
- pyoq/snapshots/routing.py +40 -0
- pyoq/snapshots/source.py +33 -0
- pyoq/tracing/__init__.py +5 -0
- pyoq/tracing/spans.py +89 -0
- pyoq/unset.py +14 -0
- pyoq_sql-1.0.2.dist-info/METADATA +3050 -0
- pyoq_sql-1.0.2.dist-info/RECORD +267 -0
- pyoq_sql-1.0.2.dist-info/WHEEL +4 -0
- pyoq_sql-1.0.2.dist-info/entry_points.txt +3 -0
- pyoq_sql-1.0.2.dist-info/licenses/LICENSE +373 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
"""Typed PostgreSQL catalog row records."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import cast
|
|
7
|
+
|
|
8
|
+
from pyoq.errors import SchemaInspectionError
|
|
9
|
+
from pyoq.schema.models import (
|
|
10
|
+
GeneratedKind,
|
|
11
|
+
Identifier,
|
|
12
|
+
KeyKind,
|
|
13
|
+
ObjectReference,
|
|
14
|
+
ReferentialAction,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
_IDENTITY_KINDS = {
|
|
18
|
+
"a": GeneratedKind.IDENTITY_ALWAYS,
|
|
19
|
+
"d": GeneratedKind.IDENTITY_BY_DEFAULT,
|
|
20
|
+
}
|
|
21
|
+
_COMPUTED_KINDS = {
|
|
22
|
+
"s": GeneratedKind.COMPUTED_STORED,
|
|
23
|
+
"v": GeneratedKind.COMPUTED_VIRTUAL,
|
|
24
|
+
}
|
|
25
|
+
_KEY_KINDS = {"p": KeyKind.PRIMARY, "u": KeyKind.UNIQUE}
|
|
26
|
+
_REFERENTIAL_ACTIONS = {
|
|
27
|
+
"a": ReferentialAction.NO_ACTION,
|
|
28
|
+
"r": ReferentialAction.RESTRICT,
|
|
29
|
+
"c": ReferentialAction.CASCADE,
|
|
30
|
+
"n": ReferentialAction.SET_NULL,
|
|
31
|
+
"d": ReferentialAction.SET_DEFAULT,
|
|
32
|
+
}
|
|
33
|
+
_DESCENDING_OPTION = 1
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True, slots=True)
|
|
37
|
+
class ObjectRecord:
|
|
38
|
+
schema: str
|
|
39
|
+
name: str
|
|
40
|
+
kind: str
|
|
41
|
+
comment: str | None
|
|
42
|
+
definition: str | None
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def is_table(self) -> bool:
|
|
46
|
+
return self.kind in {"r", "p"}
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def is_materialized(self) -> bool:
|
|
50
|
+
return self.kind == "m"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(frozen=True, slots=True)
|
|
54
|
+
class ColumnRecord:
|
|
55
|
+
schema: str
|
|
56
|
+
table: str
|
|
57
|
+
name: str
|
|
58
|
+
data_type: str
|
|
59
|
+
nullable: bool
|
|
60
|
+
type_kind: str
|
|
61
|
+
"""What the column's own type is: a base type, a domain, or an enum."""
|
|
62
|
+
|
|
63
|
+
type_schema: str
|
|
64
|
+
type_name: str
|
|
65
|
+
domain_base: str | None
|
|
66
|
+
default: str | None
|
|
67
|
+
identity: str
|
|
68
|
+
computed: str
|
|
69
|
+
comment: str | None
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def generated_kind(self) -> GeneratedKind | None:
|
|
73
|
+
identity = _IDENTITY_KINDS.get(self.identity.strip())
|
|
74
|
+
if identity is not None:
|
|
75
|
+
return identity
|
|
76
|
+
return _COMPUTED_KINDS.get(self.computed.strip())
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@dataclass(frozen=True, slots=True)
|
|
80
|
+
class ConstraintRecord:
|
|
81
|
+
schema: str
|
|
82
|
+
table: str
|
|
83
|
+
name: str
|
|
84
|
+
kind: str
|
|
85
|
+
definition: str
|
|
86
|
+
columns: tuple[str, ...]
|
|
87
|
+
target_schema: str | None
|
|
88
|
+
target_table: str | None
|
|
89
|
+
target_columns: tuple[str, ...]
|
|
90
|
+
on_update: str
|
|
91
|
+
on_delete: str
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def key_kind(self) -> KeyKind | None:
|
|
95
|
+
return _KEY_KINDS.get(self.kind)
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def target_reference(self) -> ObjectReference | None:
|
|
99
|
+
if self.target_schema is None or self.target_table is None:
|
|
100
|
+
return None
|
|
101
|
+
return ObjectReference(
|
|
102
|
+
Identifier(self.target_table),
|
|
103
|
+
Identifier(self.target_schema),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def update_action(self) -> ReferentialAction:
|
|
108
|
+
return _referential_action(self.on_update)
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def delete_action(self) -> ReferentialAction:
|
|
112
|
+
return _referential_action(self.on_delete)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass(frozen=True, slots=True)
|
|
116
|
+
class IndexRecord:
|
|
117
|
+
schema: str
|
|
118
|
+
table: str
|
|
119
|
+
name: str
|
|
120
|
+
unique: bool
|
|
121
|
+
method: str
|
|
122
|
+
predicate: str | None
|
|
123
|
+
attribute_numbers: tuple[int, ...]
|
|
124
|
+
column_names: tuple[str | None, ...]
|
|
125
|
+
definitions: tuple[str, ...]
|
|
126
|
+
options: tuple[int, ...]
|
|
127
|
+
|
|
128
|
+
def descending(self, position: int) -> bool:
|
|
129
|
+
return bool(self.options[position] & _DESCENDING_OPTION)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _referential_action(code: str) -> ReferentialAction:
|
|
133
|
+
action = _REFERENTIAL_ACTIONS.get(code.strip())
|
|
134
|
+
if action is None:
|
|
135
|
+
message = f"unsupported PostgreSQL referential action: {code!r}"
|
|
136
|
+
raise SchemaInspectionError(message)
|
|
137
|
+
return action
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def read_object(row: tuple[object, ...]) -> ObjectRecord:
|
|
141
|
+
values = _row(row, 5)
|
|
142
|
+
return ObjectRecord(
|
|
143
|
+
_text(values[0]),
|
|
144
|
+
_text(values[1]),
|
|
145
|
+
_text(values[2]),
|
|
146
|
+
_optional_text(values[3]),
|
|
147
|
+
_optional_text(values[4]),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@dataclass(frozen=True, slots=True)
|
|
152
|
+
class EnumRecord:
|
|
153
|
+
schema: str
|
|
154
|
+
name: str
|
|
155
|
+
label: str
|
|
156
|
+
comment: str | None
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def read_enum(row: tuple[object, ...]) -> EnumRecord:
|
|
160
|
+
values = _row(row, 4)
|
|
161
|
+
return EnumRecord(
|
|
162
|
+
_text(values[0]),
|
|
163
|
+
_text(values[1]),
|
|
164
|
+
_text(values[2]),
|
|
165
|
+
_optional_text(values[3]),
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@dataclass(frozen=True, slots=True)
|
|
170
|
+
class DomainRecord:
|
|
171
|
+
schema: str
|
|
172
|
+
name: str
|
|
173
|
+
base_type: str
|
|
174
|
+
not_null: bool
|
|
175
|
+
default: str | None
|
|
176
|
+
comment: str | None
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@dataclass(frozen=True, slots=True)
|
|
180
|
+
class DomainCheckRecord:
|
|
181
|
+
schema: str
|
|
182
|
+
domain: str
|
|
183
|
+
name: str
|
|
184
|
+
definition: str
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@dataclass(frozen=True, slots=True)
|
|
188
|
+
class RoutineRecord:
|
|
189
|
+
schema: str
|
|
190
|
+
name: str
|
|
191
|
+
kind: str
|
|
192
|
+
identifier: int
|
|
193
|
+
"""What the database calls this routine, which separates two of a name."""
|
|
194
|
+
|
|
195
|
+
returns: str | None
|
|
196
|
+
position: int | None
|
|
197
|
+
parameter_name: str | None
|
|
198
|
+
mode: str
|
|
199
|
+
parameter_type: str | None
|
|
200
|
+
return_type_schema: str | None
|
|
201
|
+
return_type_name: str | None
|
|
202
|
+
return_type_kind: str | None
|
|
203
|
+
return_base_type: str | None
|
|
204
|
+
return_is_array: bool
|
|
205
|
+
parameter_type_schema: str | None
|
|
206
|
+
parameter_type_name: str | None
|
|
207
|
+
parameter_type_kind: str | None
|
|
208
|
+
parameter_base_type: str | None
|
|
209
|
+
parameter_is_array: bool
|
|
210
|
+
parameter_forbids_null: bool = False
|
|
211
|
+
"""Whether the parameter's own type refuses a null, which a domain can."""
|
|
212
|
+
default_count: int = 0
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def read_domain(row: tuple[object, ...]) -> DomainRecord:
|
|
216
|
+
values = _row(row, 6)
|
|
217
|
+
return DomainRecord(
|
|
218
|
+
_text(values[0]),
|
|
219
|
+
_text(values[1]),
|
|
220
|
+
_text(values[2]),
|
|
221
|
+
_flag(values[3]),
|
|
222
|
+
_optional_text(values[4]),
|
|
223
|
+
_optional_text(values[5]),
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def read_domain_check(row: tuple[object, ...]) -> DomainCheckRecord:
|
|
228
|
+
values = _row(row, 4)
|
|
229
|
+
return DomainCheckRecord(
|
|
230
|
+
_text(values[0]),
|
|
231
|
+
_text(values[1]),
|
|
232
|
+
_text(values[2]),
|
|
233
|
+
_text(values[3]),
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def read_routine(row: tuple[object, ...]) -> RoutineRecord:
|
|
238
|
+
values = _row(row, 21)
|
|
239
|
+
return RoutineRecord(
|
|
240
|
+
_text(values[0]),
|
|
241
|
+
_text(values[1]),
|
|
242
|
+
_text(values[2]),
|
|
243
|
+
_number(values[3]),
|
|
244
|
+
_optional_text(values[4]),
|
|
245
|
+
None if values[5] is None else _number(values[5]),
|
|
246
|
+
_optional_text(values[6]),
|
|
247
|
+
_text(values[7]),
|
|
248
|
+
_optional_text(values[8]),
|
|
249
|
+
_optional_text(values[9]),
|
|
250
|
+
_optional_text(values[10]),
|
|
251
|
+
_optional_text(values[11]),
|
|
252
|
+
_optional_text(values[12]),
|
|
253
|
+
_flag(values[13]),
|
|
254
|
+
_optional_text(values[14]),
|
|
255
|
+
_optional_text(values[15]),
|
|
256
|
+
_optional_text(values[16]),
|
|
257
|
+
_optional_text(values[17]),
|
|
258
|
+
_flag(values[18]),
|
|
259
|
+
_flag(values[19]),
|
|
260
|
+
_number(values[20]),
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def read_column(row: tuple[object, ...]) -> ColumnRecord:
|
|
265
|
+
values = _row(row, 13)
|
|
266
|
+
return ColumnRecord(
|
|
267
|
+
_text(values[0]),
|
|
268
|
+
_text(values[1]),
|
|
269
|
+
_text(values[2]),
|
|
270
|
+
_text(values[3]),
|
|
271
|
+
_flag(values[4]),
|
|
272
|
+
_text(values[5]),
|
|
273
|
+
_text(values[6]),
|
|
274
|
+
_text(values[7]),
|
|
275
|
+
_optional_text(values[8]),
|
|
276
|
+
_optional_text(values[9]),
|
|
277
|
+
_text(values[10]),
|
|
278
|
+
_text(values[11]),
|
|
279
|
+
_optional_text(values[12]),
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def read_constraint(row: tuple[object, ...]) -> ConstraintRecord:
|
|
284
|
+
values = _row(row, 11)
|
|
285
|
+
return ConstraintRecord(
|
|
286
|
+
_text(values[0]),
|
|
287
|
+
_text(values[1]),
|
|
288
|
+
_text(values[2]),
|
|
289
|
+
_text(values[3]),
|
|
290
|
+
_text(values[4]),
|
|
291
|
+
_names(values[5]),
|
|
292
|
+
_optional_text(values[6]),
|
|
293
|
+
_optional_text(values[7]),
|
|
294
|
+
_names(values[8]),
|
|
295
|
+
_text(values[9]),
|
|
296
|
+
_text(values[10]),
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def read_index(row: tuple[object, ...]) -> IndexRecord:
|
|
301
|
+
values = _row(row, 10)
|
|
302
|
+
return IndexRecord(
|
|
303
|
+
_text(values[0]),
|
|
304
|
+
_text(values[1]),
|
|
305
|
+
_text(values[2]),
|
|
306
|
+
_flag(values[3]),
|
|
307
|
+
_text(values[4]),
|
|
308
|
+
_optional_text(values[5]),
|
|
309
|
+
_numbers(values[6]),
|
|
310
|
+
_optional_names(values[7]),
|
|
311
|
+
_names(values[8]),
|
|
312
|
+
_numbers(values[9]),
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def _row(row: tuple[object, ...], width: int) -> tuple[object, ...]:
|
|
317
|
+
if len(row) != width:
|
|
318
|
+
message = "PostgreSQL catalog row has an unexpected shape"
|
|
319
|
+
raise SchemaInspectionError(message)
|
|
320
|
+
return row
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def _text(value: object) -> str:
|
|
324
|
+
if not isinstance(value, str):
|
|
325
|
+
message = f"PostgreSQL catalog value is not text: {value!r}"
|
|
326
|
+
raise SchemaInspectionError(message)
|
|
327
|
+
return value
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def _optional_text(value: object) -> str | None:
|
|
331
|
+
return None if value is None else _text(value)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def _flag(value: object) -> bool:
|
|
335
|
+
if not isinstance(value, bool):
|
|
336
|
+
message = f"PostgreSQL catalog value is not a flag: {value!r}"
|
|
337
|
+
raise SchemaInspectionError(message)
|
|
338
|
+
return value
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def _names(value: object) -> tuple[str, ...]:
|
|
342
|
+
return tuple(_text(item) for item in _sequence(value))
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def _optional_names(value: object) -> tuple[str | None, ...]:
|
|
346
|
+
return tuple(_optional_text(item) for item in _sequence(value))
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def _numbers(value: object) -> tuple[int, ...]:
|
|
350
|
+
return tuple(_number(item) for item in _sequence(value))
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def _number(value: object) -> int:
|
|
354
|
+
if isinstance(value, bool) or not isinstance(value, int):
|
|
355
|
+
message = f"PostgreSQL catalog value is not a number: {value!r}"
|
|
356
|
+
raise SchemaInspectionError(message)
|
|
357
|
+
return value
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def _sequence(value: object) -> list[object]:
|
|
361
|
+
if not isinstance(value, list):
|
|
362
|
+
message = f"PostgreSQL catalog value is not an array: {value!r}"
|
|
363
|
+
raise SchemaInspectionError(message)
|
|
364
|
+
return cast("list[object]", value)
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
__all__ = (
|
|
368
|
+
"ColumnRecord",
|
|
369
|
+
"ConstraintRecord",
|
|
370
|
+
"DomainCheckRecord",
|
|
371
|
+
"DomainRecord",
|
|
372
|
+
"EnumRecord",
|
|
373
|
+
"IndexRecord",
|
|
374
|
+
"ObjectRecord",
|
|
375
|
+
"RoutineRecord",
|
|
376
|
+
"read_column",
|
|
377
|
+
"read_constraint",
|
|
378
|
+
"read_domain",
|
|
379
|
+
"read_domain_check",
|
|
380
|
+
"read_enum",
|
|
381
|
+
"read_index",
|
|
382
|
+
"read_object",
|
|
383
|
+
"read_routine",
|
|
384
|
+
)
|