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.
Files changed (60) hide show
  1. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/PKG-INFO +17 -2
  2. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/README.md +16 -1
  3. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/pyproject.toml +1 -1
  4. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/__init__.py +346 -0
  5. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/__init__.py +117 -0
  6. 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
  7. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/bit_string.py +124 -0
  8. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/geometric.py +162 -0
  9. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/json.py +195 -0
  10. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/monetary.py +204 -0
  11. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/network_address.py +297 -0
  12. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/object_identifier.py +411 -0
  13. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/pg_lsn.py +132 -0
  14. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/range.py +208 -0
  15. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/text_search.py +229 -0
  16. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/adapters/xml.py +134 -0
  17. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/backend/__init__.py +21 -0
  18. {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
  19. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/backend/base.py +193 -0
  20. 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
  21. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial/activerecord/backend/impl/postgres/config.py +2 -1
  22. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/dialect.py +845 -0
  23. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/__init__.py +178 -0
  24. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/bit_string.py +212 -0
  25. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/enum.py +160 -0
  26. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/geometric.py +225 -0
  27. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/json.py +286 -0
  28. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/functions/range.py +379 -0
  29. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/mixins.py +1004 -0
  30. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/protocols.py +1414 -0
  31. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/statements.py +405 -0
  32. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial/activerecord/backend/impl/postgres/transaction.py +2 -2
  33. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/type_compatibility.py +456 -0
  34. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/__init__.py +262 -0
  35. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/bit_string.py +123 -0
  36. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/constants.py +275 -0
  37. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/enum.py +366 -0
  38. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/geometric.py +385 -0
  39. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/json.py +197 -0
  40. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/monetary.py +137 -0
  41. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/network_address.py +233 -0
  42. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/object_identifier.py +634 -0
  43. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/pg_lsn.py +215 -0
  44. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/range.py +577 -0
  45. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/text_search.py +1099 -0
  46. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial/activerecord/backend/impl/postgres/types/xml.py +152 -0
  47. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial_activerecord_postgres.egg-info/PKG-INFO +17 -2
  48. rhosocial_activerecord_postgres-1.0.0.dev4/src/rhosocial_activerecord_postgres.egg-info/SOURCES.txt +54 -0
  49. rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres/__init__.py +0 -52
  50. rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres/dialect.py +0 -295
  51. rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial/activerecord/backend/impl/postgres/types.py +0 -220
  52. rhosocial_activerecord_postgres-1.0.0.dev3/src/rhosocial_activerecord_postgres.egg-info/SOURCES.txt +0 -19
  53. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/LICENSE +0 -0
  54. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/MANIFEST.in +0 -0
  55. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/setup.cfg +0 -0
  56. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial/activerecord/backend/impl/postgres/README.md +0 -0
  57. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial/activerecord/backend/impl/postgres/__main__.py +0 -0
  58. {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
  59. {rhosocial_activerecord_postgres-1.0.0.dev3 → rhosocial_activerecord_postgres-1.0.0.dev4}/src/rhosocial_activerecord_postgres.egg-info/requires.txt +0 -0
  60. {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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rhosocial_activerecord_postgres
3
- Version: 1.0.0.dev3
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
- | RETURNING | 8.2+ | INSERT/UPDATE/DELETE RETURNING |
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:
@@ -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
- | RETURNING | 8.2+ | INSERT/UPDATE/DELETE RETURNING |
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.dev3"
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
- import datetime
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 uuid
5
- from decimal import Decimal
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]