rhosocial-activerecord-postgres 1.0.0.dev3__tar.gz → 1.0.0.dev4__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.
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/PKG-INFO +17 -2
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/README.md +16 -1
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/pyproject.toml +1 -1
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/__init__.py +346 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/__init__.py +117 -0
- rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres/adapters.py → rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/base.py +111 -6
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/bit_string.py +124 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/geometric.py +162 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/json.py +195 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/monetary.py +204 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/network_address.py +297 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/object_identifier.py +411 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/pg_lsn.py +132 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/range.py +208 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/text_search.py +229 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/xml.py +134 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/backend/__init__.py +21 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres → rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/backend}/async_backend.py +198 -152
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/backend/base.py +193 -0
- rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres/backend.py → rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/backend/sync.py +193 -152
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial/activerecord/backend/impl/postgres/config.py +2 -1
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/dialect.py +845 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/__init__.py +178 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/bit_string.py +212 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/enum.py +160 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/geometric.py +225 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/json.py +286 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/range.py +379 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/mixins.py +1004 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/protocols.py +1414 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/statements.py +405 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial/activerecord/backend/impl/postgres/transaction.py +2 -2
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/type_compatibility.py +456 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/__init__.py +262 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/bit_string.py +123 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/constants.py +275 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/enum.py +366 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/geometric.py +385 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/json.py +197 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/monetary.py +137 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/network_address.py +233 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/object_identifier.py +634 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/pg_lsn.py +215 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/range.py +577 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/text_search.py +1099 -0
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/xml.py +152 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial_activerecord_postgres.egg-info/PKG-INFO +17 -2
- rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial_activerecord_postgres.egg-info/SOURCES.txt +54 -0
- rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres/__init__.py +0 -52
- rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres/dialect.py +0 -295
- rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres/types.py +0 -220
- rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial_activerecord_postgres.egg-info/SOURCES.txt +0 -19
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/LICENSE +0 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/MANIFEST.in +0 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/setup.cfg +0 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial/activerecord/backend/impl/postgres/README.md +0 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial/activerecord/backend/impl/postgres/__main__.py +0 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial_activerecord_postgres.egg-info/dependency_links.txt +0 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial_activerecord_postgres.egg-info/requires.txt +0 -0
- {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial_activerecord_postgres.egg-info/top_level.txt +0 -0
{rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rhosocial_activerecord_postgres
|
|
3
|
-
Version: 1.0.0.
|
|
3
|
+
Version: 1.0.0.dev4
|
|
4
4
|
Summary: postgres backend implementation for rhosocial-activerecord, providing a robust and optimized postgres database support.
|
|
5
5
|
Author-email: vistart <i@vistart.me>
|
|
6
6
|
License: Apache License
|
|
@@ -447,15 +447,30 @@ print(user.id) # Populated automatically via RETURNING
|
|
|
447
447
|
| Feature | Min Version | Notes |
|
|
448
448
|
|---------|-------------|-------|
|
|
449
449
|
| Basic operations | 8.0+ | Core functionality |
|
|
450
|
+
| RETURNING | 8.2+ | INSERT/UPDATE/DELETE RETURNING |
|
|
450
451
|
| CTEs | 8.4+ | WITH clauses |
|
|
451
452
|
| Window functions | 8.4+ | ROW_NUMBER, RANK, etc. |
|
|
452
|
-
|
|
|
453
|
+
| TRUNCATE RESTART IDENTITY | 8.4+ | Reset sequences on truncate |
|
|
453
454
|
| JSON | 9.2+ | Basic JSON support |
|
|
455
|
+
| LATERAL joins | 9.3+ | LATERAL keyword |
|
|
454
456
|
| JSONB | 9.4+ | Binary JSON, indexed |
|
|
457
|
+
| FILTER clause | 9.4+ | Aggregate FILTER |
|
|
458
|
+
| Ordered-set aggregates | 9.4+ | PERCENTILE_CONT, etc. |
|
|
455
459
|
| UPSERT | 9.5+ | INSERT ... ON CONFLICT |
|
|
460
|
+
| Advanced grouping | 9.5+ | ROLLUP, CUBE, GROUPING SETS |
|
|
461
|
+
| SKIP LOCKED | 9.5+ | FOR UPDATE SKIP LOCKED |
|
|
462
|
+
| MATERIALIZED CTE hints | 12.0+ | MATERIALIZED/NOT MATERIALIZED |
|
|
463
|
+
| JSON_TABLE | 12.0+ | JSON table function |
|
|
464
|
+
| MERGE | 15.0+ | MERGE statement |
|
|
465
|
+
|
|
466
|
+
**Supported SQL Protocols:**
|
|
467
|
+
- ✅ SetOperationSupport (UNION, INTERSECT, EXCEPT) — All versions
|
|
468
|
+
- ✅ TruncateSupport (TRUNCATE TABLE) — All versions; RESTART IDENTITY ≥ 8.4
|
|
456
469
|
|
|
457
470
|
**Recommended**: PostgreSQL 12+ for optimal feature support.
|
|
458
471
|
|
|
472
|
+
See [PROTOCOL_SUPPORT.md](docs/PROTOCOL_SUPPORT.md) for complete protocol support matrix.
|
|
473
|
+
|
|
459
474
|
## Get Started with AI Code Agents
|
|
460
475
|
|
|
461
476
|
This project supports AI-assisted development:
|
{rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/README.md
RENAMED
|
@@ -196,15 +196,30 @@ print(user.id) # Populated automatically via RETURNING
|
|
|
196
196
|
| Feature | Min Version | Notes |
|
|
197
197
|
|---------|-------------|-------|
|
|
198
198
|
| Basic operations | 8.0+ | Core functionality |
|
|
199
|
+
| RETURNING | 8.2+ | INSERT/UPDATE/DELETE RETURNING |
|
|
199
200
|
| CTEs | 8.4+ | WITH clauses |
|
|
200
201
|
| Window functions | 8.4+ | ROW_NUMBER, RANK, etc. |
|
|
201
|
-
|
|
|
202
|
+
| TRUNCATE RESTART IDENTITY | 8.4+ | Reset sequences on truncate |
|
|
202
203
|
| JSON | 9.2+ | Basic JSON support |
|
|
204
|
+
| LATERAL joins | 9.3+ | LATERAL keyword |
|
|
203
205
|
| JSONB | 9.4+ | Binary JSON, indexed |
|
|
206
|
+
| FILTER clause | 9.4+ | Aggregate FILTER |
|
|
207
|
+
| Ordered-set aggregates | 9.4+ | PERCENTILE_CONT, etc. |
|
|
204
208
|
| UPSERT | 9.5+ | INSERT ... ON CONFLICT |
|
|
209
|
+
| Advanced grouping | 9.5+ | ROLLUP, CUBE, GROUPING SETS |
|
|
210
|
+
| SKIP LOCKED | 9.5+ | FOR UPDATE SKIP LOCKED |
|
|
211
|
+
| MATERIALIZED CTE hints | 12.0+ | MATERIALIZED/NOT MATERIALIZED |
|
|
212
|
+
| JSON_TABLE | 12.0+ | JSON table function |
|
|
213
|
+
| MERGE | 15.0+ | MERGE statement |
|
|
214
|
+
|
|
215
|
+
**Supported SQL Protocols:**
|
|
216
|
+
- ✅ SetOperationSupport (UNION, INTERSECT, EXCEPT) — All versions
|
|
217
|
+
- ✅ TruncateSupport (TRUNCATE TABLE) — All versions; RESTART IDENTITY ≥ 8.4
|
|
205
218
|
|
|
206
219
|
**Recommended**: PostgreSQL 12+ for optimal feature support.
|
|
207
220
|
|
|
221
|
+
See [PROTOCOL_SUPPORT.md](docs/PROTOCOL_SUPPORT.md) for complete protocol support matrix.
|
|
222
|
+
|
|
208
223
|
## Get Started with AI Code Agents
|
|
209
224
|
|
|
210
225
|
This project supports AI-assisted development:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rhosocial_activerecord_postgres"
|
|
7
|
-
version = "1.0.0.
|
|
7
|
+
version = "1.0.0.dev4"
|
|
8
8
|
description = "postgres backend implementation for rhosocial-activerecord, providing a robust and optimized postgres database support."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# src/rhosocial/activerecord/backend/impl/postgres/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
PostgreSQL backend implementation for the Python ORM.
|
|
4
|
+
|
|
5
|
+
This module provides:
|
|
6
|
+
- PostgreSQL synchronous backend with connection management and query execution
|
|
7
|
+
- PostgreSQL asynchronous backend with async/await support
|
|
8
|
+
- PostgreSQL-specific connection configuration
|
|
9
|
+
- Type mapping and value conversion
|
|
10
|
+
- Transaction management with savepoint support (sync and async)
|
|
11
|
+
- PostgreSQL dialect and expression handling
|
|
12
|
+
- PostgreSQL-specific type definitions and mappings
|
|
13
|
+
|
|
14
|
+
Architecture:
|
|
15
|
+
- PostgreSQLBackend: Synchronous implementation using psycopg
|
|
16
|
+
- AsyncPostgreSQLBackend: Asynchronous implementation using psycopg
|
|
17
|
+
- Independent from ORM frameworks - uses only native drivers
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from .backend import PostgresBackend, AsyncPostgresBackend
|
|
21
|
+
from .config import PostgresConnectionConfig
|
|
22
|
+
from .dialect import PostgresDialect
|
|
23
|
+
from .transaction import PostgresTransactionManager, AsyncPostgresTransactionManager
|
|
24
|
+
from .types import PostgresEnumType
|
|
25
|
+
from .statements import (
|
|
26
|
+
CreateEnumTypeExpression,
|
|
27
|
+
DropEnumTypeExpression,
|
|
28
|
+
AlterEnumTypeAddValueExpression,
|
|
29
|
+
AlterEnumTypeRenameValueExpression,
|
|
30
|
+
CreateRangeTypeExpression,
|
|
31
|
+
)
|
|
32
|
+
from .adapters import (
|
|
33
|
+
PostgresEnumAdapter,
|
|
34
|
+
PostgresRangeAdapter,
|
|
35
|
+
PostgresMultirangeAdapter,
|
|
36
|
+
)
|
|
37
|
+
from .types.range import (
|
|
38
|
+
PostgresRange,
|
|
39
|
+
PostgresMultirange,
|
|
40
|
+
)
|
|
41
|
+
from .types.geometric import (
|
|
42
|
+
Point,
|
|
43
|
+
Line,
|
|
44
|
+
LineSegment,
|
|
45
|
+
Box,
|
|
46
|
+
Path,
|
|
47
|
+
Polygon,
|
|
48
|
+
Circle,
|
|
49
|
+
)
|
|
50
|
+
from .adapters.geometric import PostgresGeometryAdapter
|
|
51
|
+
from .types.bit_string import PostgresBitString
|
|
52
|
+
from .adapters.bit_string import PostgresBitStringAdapter
|
|
53
|
+
from .types.monetary import PostgresMoney
|
|
54
|
+
from .adapters.monetary import PostgresMoneyAdapter
|
|
55
|
+
from .types.xml import PostgresXML
|
|
56
|
+
from .adapters.xml import PostgresXMLAdapter
|
|
57
|
+
from .types.network_address import PostgresMacaddr, PostgresMacaddr8
|
|
58
|
+
from .adapters.network_address import PostgresMacaddrAdapter, PostgresMacaddr8Adapter
|
|
59
|
+
from .types.text_search import (
|
|
60
|
+
PostgresTsVector,
|
|
61
|
+
PostgresTsQuery,
|
|
62
|
+
to_tsvector,
|
|
63
|
+
to_tsquery,
|
|
64
|
+
plainto_tsquery,
|
|
65
|
+
phraseto_tsquery,
|
|
66
|
+
websearch_to_tsquery,
|
|
67
|
+
ts_matches,
|
|
68
|
+
ts_matches_expr,
|
|
69
|
+
ts_rank,
|
|
70
|
+
ts_rank_cd,
|
|
71
|
+
ts_headline,
|
|
72
|
+
tsvector_concat,
|
|
73
|
+
tsvector_strip,
|
|
74
|
+
tsvector_setweight,
|
|
75
|
+
tsvector_length,
|
|
76
|
+
)
|
|
77
|
+
from .adapters.text_search import PostgresTsVectorAdapter, PostgresTsQueryAdapter
|
|
78
|
+
from .types.pg_lsn import PostgresLsn
|
|
79
|
+
from .adapters.pg_lsn import PostgresLsnAdapter
|
|
80
|
+
from .types.object_identifier import (
|
|
81
|
+
OID,
|
|
82
|
+
RegClass,
|
|
83
|
+
RegType,
|
|
84
|
+
RegProc,
|
|
85
|
+
RegProcedure,
|
|
86
|
+
RegOper,
|
|
87
|
+
RegOperator,
|
|
88
|
+
RegConfig,
|
|
89
|
+
RegDictionary,
|
|
90
|
+
RegNamespace,
|
|
91
|
+
RegRole,
|
|
92
|
+
RegCollation,
|
|
93
|
+
XID,
|
|
94
|
+
XID8,
|
|
95
|
+
CID,
|
|
96
|
+
TID,
|
|
97
|
+
)
|
|
98
|
+
from .adapters.object_identifier import PostgresOidAdapter, PostgresXidAdapter, PostgresTidAdapter
|
|
99
|
+
from .types.json import PostgresJsonPath
|
|
100
|
+
from .adapters.json import PostgresJsonPathAdapter
|
|
101
|
+
from .types.enum import EnumTypeManager
|
|
102
|
+
|
|
103
|
+
# Import functions from functions module
|
|
104
|
+
from .functions import (
|
|
105
|
+
# Range functions
|
|
106
|
+
range_contains,
|
|
107
|
+
range_contained_by,
|
|
108
|
+
range_contains_range,
|
|
109
|
+
range_overlaps,
|
|
110
|
+
range_adjacent,
|
|
111
|
+
range_strictly_left_of,
|
|
112
|
+
range_strictly_right_of,
|
|
113
|
+
range_not_extend_right,
|
|
114
|
+
range_not_extend_left,
|
|
115
|
+
range_union,
|
|
116
|
+
range_intersection,
|
|
117
|
+
range_difference,
|
|
118
|
+
range_lower,
|
|
119
|
+
range_upper,
|
|
120
|
+
range_is_empty,
|
|
121
|
+
range_lower_inc,
|
|
122
|
+
range_upper_inc,
|
|
123
|
+
range_lower_inf,
|
|
124
|
+
range_upper_inf,
|
|
125
|
+
# Geometry functions
|
|
126
|
+
geometry_distance,
|
|
127
|
+
geometry_contains,
|
|
128
|
+
geometry_contained_by,
|
|
129
|
+
geometry_overlaps,
|
|
130
|
+
geometry_strictly_left,
|
|
131
|
+
geometry_strictly_right,
|
|
132
|
+
geometry_not_extend_right,
|
|
133
|
+
geometry_not_extend_left,
|
|
134
|
+
geometry_area,
|
|
135
|
+
geometry_center,
|
|
136
|
+
geometry_length,
|
|
137
|
+
geometry_width,
|
|
138
|
+
geometry_height,
|
|
139
|
+
geometry_npoints,
|
|
140
|
+
# Enum functions
|
|
141
|
+
enum_range,
|
|
142
|
+
enum_first,
|
|
143
|
+
enum_last,
|
|
144
|
+
enum_lt,
|
|
145
|
+
enum_le,
|
|
146
|
+
enum_gt,
|
|
147
|
+
enum_ge,
|
|
148
|
+
# Bit string functions
|
|
149
|
+
bit_concat,
|
|
150
|
+
bit_and,
|
|
151
|
+
bit_or,
|
|
152
|
+
bit_xor,
|
|
153
|
+
bit_not,
|
|
154
|
+
bit_shift_left,
|
|
155
|
+
bit_shift_right,
|
|
156
|
+
bit_length,
|
|
157
|
+
bit_length_func,
|
|
158
|
+
bit_octet_length,
|
|
159
|
+
bit_get_bit,
|
|
160
|
+
bit_set_bit,
|
|
161
|
+
bit_count,
|
|
162
|
+
# JSON functions
|
|
163
|
+
json_path_root,
|
|
164
|
+
json_path_key,
|
|
165
|
+
json_path_index,
|
|
166
|
+
json_path_wildcard,
|
|
167
|
+
json_path_filter,
|
|
168
|
+
jsonb_path_query,
|
|
169
|
+
jsonb_path_query_first,
|
|
170
|
+
jsonb_path_exists,
|
|
171
|
+
jsonb_path_match,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
__all__ = [
|
|
176
|
+
# Synchronous Backend
|
|
177
|
+
'PostgresBackend',
|
|
178
|
+
|
|
179
|
+
# Asynchronous Backend
|
|
180
|
+
'AsyncPostgresBackend',
|
|
181
|
+
|
|
182
|
+
# Configuration
|
|
183
|
+
'PostgresConnectionConfig',
|
|
184
|
+
|
|
185
|
+
# Dialect related
|
|
186
|
+
'PostgresDialect',
|
|
187
|
+
|
|
188
|
+
# Transaction - Sync and Async
|
|
189
|
+
'PostgresTransactionManager',
|
|
190
|
+
'AsyncPostgresTransactionManager',
|
|
191
|
+
|
|
192
|
+
# PostgreSQL-specific Type Helpers
|
|
193
|
+
'PostgresEnumType',
|
|
194
|
+
'PostgresEnumAdapter',
|
|
195
|
+
|
|
196
|
+
# PostgreSQL DDL Statements
|
|
197
|
+
'CreateEnumTypeExpression',
|
|
198
|
+
'DropEnumTypeExpression',
|
|
199
|
+
'AlterEnumTypeAddValueExpression',
|
|
200
|
+
'AlterEnumTypeRenameValueExpression',
|
|
201
|
+
'CreateRangeTypeExpression',
|
|
202
|
+
|
|
203
|
+
# Range Types
|
|
204
|
+
'PostgresRange',
|
|
205
|
+
'PostgresRangeAdapter',
|
|
206
|
+
'PostgresMultirange',
|
|
207
|
+
'PostgresMultirangeAdapter',
|
|
208
|
+
'range_contains',
|
|
209
|
+
'range_contained_by',
|
|
210
|
+
'range_contains_range',
|
|
211
|
+
'range_overlaps',
|
|
212
|
+
'range_adjacent',
|
|
213
|
+
'range_strictly_left_of',
|
|
214
|
+
'range_strictly_right_of',
|
|
215
|
+
'range_not_extend_right',
|
|
216
|
+
'range_not_extend_left',
|
|
217
|
+
'range_union',
|
|
218
|
+
'range_intersection',
|
|
219
|
+
'range_difference',
|
|
220
|
+
'range_lower',
|
|
221
|
+
'range_upper',
|
|
222
|
+
'range_is_empty',
|
|
223
|
+
'range_lower_inc',
|
|
224
|
+
'range_upper_inc',
|
|
225
|
+
'range_lower_inf',
|
|
226
|
+
'range_upper_inf',
|
|
227
|
+
|
|
228
|
+
# Geometry Types
|
|
229
|
+
'Point',
|
|
230
|
+
'Line',
|
|
231
|
+
'LineSegment',
|
|
232
|
+
'Box',
|
|
233
|
+
'Path',
|
|
234
|
+
'Polygon',
|
|
235
|
+
'Circle',
|
|
236
|
+
'PostgresGeometryAdapter',
|
|
237
|
+
'geometry_distance',
|
|
238
|
+
'geometry_contains',
|
|
239
|
+
'geometry_contained_by',
|
|
240
|
+
'geometry_overlaps',
|
|
241
|
+
'geometry_strictly_left',
|
|
242
|
+
'geometry_strictly_right',
|
|
243
|
+
'geometry_not_extend_right',
|
|
244
|
+
'geometry_not_extend_left',
|
|
245
|
+
'geometry_area',
|
|
246
|
+
'geometry_center',
|
|
247
|
+
'geometry_length',
|
|
248
|
+
'geometry_width',
|
|
249
|
+
'geometry_height',
|
|
250
|
+
'geometry_npoints',
|
|
251
|
+
|
|
252
|
+
# Bit String Types
|
|
253
|
+
'PostgresBitString',
|
|
254
|
+
'PostgresBitStringAdapter',
|
|
255
|
+
'bit_concat',
|
|
256
|
+
'bit_and',
|
|
257
|
+
'bit_or',
|
|
258
|
+
'bit_xor',
|
|
259
|
+
'bit_not',
|
|
260
|
+
'bit_shift_left',
|
|
261
|
+
'bit_shift_right',
|
|
262
|
+
'bit_length',
|
|
263
|
+
'bit_length_func',
|
|
264
|
+
'bit_octet_length',
|
|
265
|
+
'bit_get_bit',
|
|
266
|
+
'bit_set_bit',
|
|
267
|
+
'bit_count',
|
|
268
|
+
|
|
269
|
+
# Enum Types
|
|
270
|
+
'EnumTypeManager',
|
|
271
|
+
'enum_range',
|
|
272
|
+
'enum_first',
|
|
273
|
+
'enum_last',
|
|
274
|
+
'enum_lt',
|
|
275
|
+
'enum_le',
|
|
276
|
+
'enum_gt',
|
|
277
|
+
'enum_ge',
|
|
278
|
+
|
|
279
|
+
# Money Type
|
|
280
|
+
'PostgresMoney',
|
|
281
|
+
'PostgresMoneyAdapter',
|
|
282
|
+
|
|
283
|
+
# XML Type
|
|
284
|
+
'PostgresXML',
|
|
285
|
+
'PostgresXMLAdapter',
|
|
286
|
+
|
|
287
|
+
# MACADDR Types
|
|
288
|
+
'PostgresMacaddr',
|
|
289
|
+
'PostgresMacaddrAdapter',
|
|
290
|
+
'PostgresMacaddr8',
|
|
291
|
+
'PostgresMacaddr8Adapter',
|
|
292
|
+
|
|
293
|
+
# Text Search Types
|
|
294
|
+
'PostgresTsVector',
|
|
295
|
+
'PostgresTsVectorAdapter',
|
|
296
|
+
'PostgresTsQuery',
|
|
297
|
+
'PostgresTsQueryAdapter',
|
|
298
|
+
'to_tsvector',
|
|
299
|
+
'to_tsquery',
|
|
300
|
+
'plainto_tsquery',
|
|
301
|
+
'phraseto_tsquery',
|
|
302
|
+
'websearch_to_tsquery',
|
|
303
|
+
'ts_matches',
|
|
304
|
+
'ts_matches_expr',
|
|
305
|
+
'ts_rank',
|
|
306
|
+
'ts_rank_cd',
|
|
307
|
+
'ts_headline',
|
|
308
|
+
'tsvector_concat',
|
|
309
|
+
'tsvector_strip',
|
|
310
|
+
'tsvector_setweight',
|
|
311
|
+
'tsvector_length',
|
|
312
|
+
|
|
313
|
+
# LSN Type
|
|
314
|
+
'PostgresLsn',
|
|
315
|
+
'PostgresLsnAdapter',
|
|
316
|
+
|
|
317
|
+
# OID Types
|
|
318
|
+
'OID',
|
|
319
|
+
'RegClass',
|
|
320
|
+
'RegType',
|
|
321
|
+
'RegProc',
|
|
322
|
+
'RegProcedure',
|
|
323
|
+
'RegOper',
|
|
324
|
+
'RegOperator',
|
|
325
|
+
'RegConfig',
|
|
326
|
+
'RegDictionary',
|
|
327
|
+
'RegNamespace',
|
|
328
|
+
'RegRole',
|
|
329
|
+
'RegCollation',
|
|
330
|
+
'XID',
|
|
331
|
+
'XID8',
|
|
332
|
+
'CID',
|
|
333
|
+
'TID',
|
|
334
|
+
'PostgresOidAdapter',
|
|
335
|
+
'PostgresXidAdapter',
|
|
336
|
+
'PostgresTidAdapter',
|
|
337
|
+
|
|
338
|
+
# JSON Path Type
|
|
339
|
+
'PostgresJsonPath',
|
|
340
|
+
'PostgresJsonPathAdapter',
|
|
341
|
+
'json_path_root',
|
|
342
|
+
'json_path_key',
|
|
343
|
+
'json_path_index',
|
|
344
|
+
'json_path_wildcard',
|
|
345
|
+
'json_path_filter',
|
|
346
|
+
]
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# src/rhosocial/activerecord/backend/impl/postgres/adapters/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
PostgreSQL type adapters.
|
|
4
|
+
|
|
5
|
+
This module exports all type adapters for PostgreSQL-specific types,
|
|
6
|
+
organized according to PostgreSQL documentation structure.
|
|
7
|
+
|
|
8
|
+
PostgreSQL Documentation: https://www.postgresql.org/docs/current/datatype.html
|
|
9
|
+
|
|
10
|
+
Adapter modules and their corresponding PostgreSQL documentation:
|
|
11
|
+
- base: Basic types (array, jsonb, network address, enum)
|
|
12
|
+
- monetary: MONEY type - https://www.postgresql.org/docs/current/datatype-money.html
|
|
13
|
+
- network_address: Network address types (inet, cidr, macaddr, macaddr8) - https://www.postgresql.org/docs/current/datatype-net-types.html
|
|
14
|
+
- geometric: Geometric types (point, line, lseg, box, path, polygon, circle) - https://www.postgresql.org/docs/current/datatype-geometric.html
|
|
15
|
+
- bit_string: Bit string types (bit, varbit) - https://www.postgresql.org/docs/current/datatype-bit.html
|
|
16
|
+
- text_search: Text search types (tsvector, tsquery) - https://www.postgresql.org/docs/current/datatype-textsearch.html
|
|
17
|
+
- object_identifier: Object identifier types (oid, regclass, etc.) - https://www.postgresql.org/docs/current/datatype-oid.html
|
|
18
|
+
- json: JSON types (json, jsonb, jsonpath) - https://www.postgresql.org/docs/current/datatype-json.html
|
|
19
|
+
- range: Range types - https://www.postgresql.org/docs/current/rangetypes.html
|
|
20
|
+
- enum: Enum types - https://www.postgresql.org/docs/current/datatype-enum.html
|
|
21
|
+
- xml: XML type - https://www.postgresql.org/docs/current/datatype-xml.html
|
|
22
|
+
- pg_lsn: pg_lsn type - https://www.postgresql.org/docs/current/datatype-pg-lsn.html
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# Base types
|
|
26
|
+
from .base import (
|
|
27
|
+
PostgresListAdapter,
|
|
28
|
+
PostgresJSONBAdapter,
|
|
29
|
+
PostgresEnumAdapter,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Monetary types
|
|
33
|
+
from .monetary import PostgresMoneyAdapter
|
|
34
|
+
|
|
35
|
+
# Network address types
|
|
36
|
+
from .network_address import (
|
|
37
|
+
PostgresNetworkAddressAdapter,
|
|
38
|
+
PostgresMacaddrAdapter,
|
|
39
|
+
PostgresMacaddr8Adapter,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Geometric types
|
|
43
|
+
from .geometric import PostgresGeometryAdapter
|
|
44
|
+
|
|
45
|
+
# Bit string types
|
|
46
|
+
from .bit_string import PostgresBitStringAdapter
|
|
47
|
+
|
|
48
|
+
# Text search types
|
|
49
|
+
from .text_search import (
|
|
50
|
+
PostgresTsVectorAdapter,
|
|
51
|
+
PostgresTsQueryAdapter,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Object identifier types
|
|
55
|
+
from .object_identifier import (
|
|
56
|
+
PostgresOidAdapter,
|
|
57
|
+
PostgresXidAdapter,
|
|
58
|
+
PostgresTidAdapter,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# JSON types
|
|
62
|
+
from .json import PostgresJsonPathAdapter
|
|
63
|
+
|
|
64
|
+
# Range types
|
|
65
|
+
from .range import (
|
|
66
|
+
PostgresRangeAdapter,
|
|
67
|
+
PostgresMultirangeAdapter,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# pg_lsn type
|
|
71
|
+
from .pg_lsn import PostgresLsnAdapter
|
|
72
|
+
|
|
73
|
+
# XML type
|
|
74
|
+
from .xml import PostgresXMLAdapter
|
|
75
|
+
|
|
76
|
+
__all__ = [
|
|
77
|
+
# Basic types
|
|
78
|
+
'PostgresListAdapter',
|
|
79
|
+
'PostgresJSONBAdapter',
|
|
80
|
+
'PostgresNetworkAddressAdapter',
|
|
81
|
+
'PostgresEnumAdapter',
|
|
82
|
+
|
|
83
|
+
# Monetary types
|
|
84
|
+
'PostgresMoneyAdapter',
|
|
85
|
+
|
|
86
|
+
# Network address types
|
|
87
|
+
'PostgresMacaddrAdapter',
|
|
88
|
+
'PostgresMacaddr8Adapter',
|
|
89
|
+
|
|
90
|
+
# Geometric types
|
|
91
|
+
'PostgresGeometryAdapter',
|
|
92
|
+
|
|
93
|
+
# Bit string types
|
|
94
|
+
'PostgresBitStringAdapter',
|
|
95
|
+
|
|
96
|
+
# Text search types
|
|
97
|
+
'PostgresTsVectorAdapter',
|
|
98
|
+
'PostgresTsQueryAdapter',
|
|
99
|
+
|
|
100
|
+
# Object identifier types
|
|
101
|
+
'PostgresOidAdapter',
|
|
102
|
+
'PostgresXidAdapter',
|
|
103
|
+
'PostgresTidAdapter',
|
|
104
|
+
|
|
105
|
+
# JSON types
|
|
106
|
+
'PostgresJsonPathAdapter',
|
|
107
|
+
|
|
108
|
+
# Range types
|
|
109
|
+
'PostgresRangeAdapter',
|
|
110
|
+
'PostgresMultirangeAdapter',
|
|
111
|
+
|
|
112
|
+
# pg_lsn type
|
|
113
|
+
'PostgresLsnAdapter',
|
|
114
|
+
|
|
115
|
+
# XML type
|
|
116
|
+
'PostgresXMLAdapter',
|
|
117
|
+
]
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
# src/rhosocial/activerecord/backend/impl/postgres/adapters.py
|
|
2
|
-
|
|
1
|
+
# src/rhosocial/activerecord/backend/impl/postgres/adapters/base.py
|
|
2
|
+
"""
|
|
3
|
+
Base PostgreSQL type adapters.
|
|
4
|
+
|
|
5
|
+
This module contains basic type adapters for PostgreSQL.
|
|
6
|
+
"""
|
|
3
7
|
import json
|
|
4
|
-
import
|
|
5
|
-
from
|
|
6
|
-
from typing import Any, Dict, List, Type, Union, Optional
|
|
8
|
+
from enum import Enum as PythonEnum
|
|
9
|
+
from typing import Any, Dict, List, Type, Union, Optional, Set
|
|
7
10
|
|
|
8
11
|
from psycopg.types.json import Jsonb
|
|
9
12
|
|
|
10
13
|
from rhosocial.activerecord.backend.type_adapter import SQLTypeAdapter
|
|
11
|
-
from rhosocial.activerecord.backend.schema import DatabaseType
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
class PostgresListAdapter(SQLTypeAdapter):
|
|
@@ -108,3 +110,106 @@ class PostgresNetworkAddressAdapter(SQLTypeAdapter):
|
|
|
108
110
|
return ipaddress.ip_network(value)
|
|
109
111
|
except (ImportError, ValueError):
|
|
110
112
|
return value
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class PostgresEnumAdapter(SQLTypeAdapter):
|
|
116
|
+
"""PostgreSQL ENUM type adapter.
|
|
117
|
+
|
|
118
|
+
This adapter handles conversion between Python values and PostgreSQL enum values.
|
|
119
|
+
|
|
120
|
+
The adapter can work with:
|
|
121
|
+
- String values (validated against enum type)
|
|
122
|
+
- Python Enum instances
|
|
123
|
+
- None (NULL)
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def supported_types(self) -> Dict[Type, Set[Type]]:
|
|
128
|
+
"""Return supported type mappings."""
|
|
129
|
+
return {str: {str}}
|
|
130
|
+
|
|
131
|
+
def to_database(
|
|
132
|
+
self,
|
|
133
|
+
value: Any,
|
|
134
|
+
target_type: Type,
|
|
135
|
+
options: Optional[Dict[str, Any]] = None
|
|
136
|
+
) -> Optional[str]:
|
|
137
|
+
"""Convert Python value to PostgreSQL enum value.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
value: String, Python Enum, or None
|
|
141
|
+
target_type: Target type (not used for enums)
|
|
142
|
+
options: Optional conversion options
|
|
143
|
+
- 'enum_type': PostgresEnumType for validation
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
Enum value string, or None
|
|
147
|
+
"""
|
|
148
|
+
if value is None:
|
|
149
|
+
return None
|
|
150
|
+
|
|
151
|
+
# Handle Python Enum
|
|
152
|
+
if isinstance(value, PythonEnum):
|
|
153
|
+
result = value.name
|
|
154
|
+
elif isinstance(value, str):
|
|
155
|
+
result = value
|
|
156
|
+
else:
|
|
157
|
+
raise TypeError(f"Cannot convert {type(value).__name__} to enum value")
|
|
158
|
+
|
|
159
|
+
# Validate if enum_type provided
|
|
160
|
+
if options and 'enum_type' in options:
|
|
161
|
+
from ..types import PostgresEnumType
|
|
162
|
+
enum_type = options['enum_type']
|
|
163
|
+
if isinstance(enum_type, PostgresEnumType):
|
|
164
|
+
if not enum_type.validate_value(result):
|
|
165
|
+
raise ValueError(f"Invalid enum value: '{result}'")
|
|
166
|
+
|
|
167
|
+
return result
|
|
168
|
+
|
|
169
|
+
def from_database(
|
|
170
|
+
self,
|
|
171
|
+
value: Any,
|
|
172
|
+
target_type: Type,
|
|
173
|
+
options: Optional[Dict[str, Any]] = None
|
|
174
|
+
) -> Optional[str]:
|
|
175
|
+
"""Convert PostgreSQL enum value to Python string.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
value: Enum value from database
|
|
179
|
+
target_type: Target Python type
|
|
180
|
+
options: Optional conversion options
|
|
181
|
+
- 'enum_class': Python Enum class to convert to
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
String value, Python Enum instance, or None
|
|
185
|
+
"""
|
|
186
|
+
if value is None:
|
|
187
|
+
return None
|
|
188
|
+
|
|
189
|
+
# If already a string, check if we should convert to Python Enum
|
|
190
|
+
if isinstance(value, str):
|
|
191
|
+
if options and 'enum_class' in options:
|
|
192
|
+
enum_class = options['enum_class']
|
|
193
|
+
if issubclass(enum_class, PythonEnum):
|
|
194
|
+
return enum_class[value]
|
|
195
|
+
return value
|
|
196
|
+
|
|
197
|
+
raise TypeError(f"Cannot convert {type(value).__name__} from enum")
|
|
198
|
+
|
|
199
|
+
def to_database_batch(
|
|
200
|
+
self,
|
|
201
|
+
values: List[Any],
|
|
202
|
+
target_type: Type,
|
|
203
|
+
options: Optional[Dict[str, Any]] = None
|
|
204
|
+
) -> List[Any]:
|
|
205
|
+
"""Batch convert values to database format."""
|
|
206
|
+
return [self.to_database(v, target_type, options) for v in values]
|
|
207
|
+
|
|
208
|
+
def from_database_batch(
|
|
209
|
+
self,
|
|
210
|
+
values: List[Any],
|
|
211
|
+
target_type: Type,
|
|
212
|
+
options: Optional[Dict[str, Any]] = None
|
|
213
|
+
) -> List[Any]:
|
|
214
|
+
"""Batch convert values from database format."""
|
|
215
|
+
return [self.from_database(v, target_type, options) for v in values]
|