Skip to content

Add bidirectional domain conversion with JSON Queries - #38

Merged
polsala merged 10 commits into
masterfrom
copilot/fix-1f10535f-5a7b-426a-ba17-7eec97e375a3
Sep 4, 2025
Merged

Add bidirectional domain conversion with JSON Queries#38
polsala merged 10 commits into
masterfrom
copilot/fix-1f10535f-5a7b-426a-ba17-7eec97e375a3

Conversation

Copilot AI commented Sep 2, 2025

Copy link
Copy Markdown
Contributor

This PR adds comprehensive bidirectional conversion functionality between OpenERP/Odoo domains and structured JSON format, with correct handling of OpenERP/Odoo's flat prefix notation and proper semantic preservation of nested query structures.

Key Features

Domain to JSON Conversion

  • Converts OpenERP/Odoo domain arrays to structured JSON with combinator and rules structure
  • Maps domain operators to standardized JSON operators (e.g., ilikecontains, <>!=)
  • Supports complex AND (&) and OR (|) domain logic with prefix notation parsing
  • Handles nested domain structures correctly with recursive parsing
  • Automatically flattens nested queries with same combinator for cleaner output

JSON to Domain Conversion

  • Converts JSON query structure back to OpenERP/Odoo domain arrays using correct flat prefix notation
  • Generates domains like ['|', '|', ('a', '=', 1), ('b', '=', 2), ('c', '=', 3)] instead of nested structures
  • Handles both AND (simple array) and OR (flat prefix notation) combinators
  • Supports nested queries with proper flattening (no nested lists)
  • Special handling for 'in' operator with string values (comma-separated)
  • Preserves explicit AND operators in nested query structures for semantic correctness
  • Round-trip conversion consistency for all domain structures

Critical Fix for Semantic Preservation

The implementation correctly generates OpenERP/Odoo domains using flat prefix notation while preserving semantic grouping:

  • Multiple OR operations: ['|', '|', rule1, rule2, rule3] (not nested structures)
  • Mixed operations: [('active', '=', True), '|', ('state', '=', 'open'), ('state', '=', 'draft')]
  • Nested AND groups within OR: ['|', ('name', '=', 'John'), '&', ('age', '>', 18), ('city', '=', 'Barcelona')]
  • Complex roundtrip preservation: ['|', '&', ('name', 'ilike', 'John'), ('age', '>', 18), '&', ('city', '=', 'Barcelona'), ('active', '=', True)]

No nested lists - domains are always flat arrays of operators and tuples, but explicit operators are preserved when semantically necessary.

Usage Examples

from ooquery import convert_from_domain, convert_to_domain

# Multiple OR conversion (flat prefix notation)
domain = ['|', '|', ('state', '=', 'open'), ('state', '=', 'draft'), ('state', '=', 'pending')]
json_query = convert_from_domain(domain)
back_to_domain = convert_to_domain(json_query)
# Result: ['|', '|', ('state', '=', 'open'), ('state', '=', 'draft'), ('state', '=', 'pending')]

# Nested AND within OR (preserves explicit operators for correct semantics)
query = {
    'combinator': 'or',
    'rules': [
        {'field': 'name', 'operator': '=', 'value': 'John'},
        {
            'combinator': 'and',
            'rules': [
                {'field': 'age', 'operator': '>', 'value': 18},
                {'field': 'city', 'operator': '=', 'value': 'Barcelona'}
            ]
        }
    ]
}
domain = convert_to_domain(query)
# Result: ['|', ('name', '=', 'John'), '&', ('age', '>', 18), ('city', '=', 'Barcelona')]
# Semantics: OR between "name=John" and "(age>18 AND city=Barcelona)"

# Complex prefix notation roundtrip
original = ['|', '&', ('name', 'ilike', 'John'), ('age', '>', 18), '&', ('city', '=', 'Barcelona'), ('active', '=', True)]
json_query = convert_from_domain(original)
result = convert_to_domain(json_query)
# Result: exact same as original - perfect roundtrip consistency

Implementation Details

  • Stack-based parsing for correct prefix notation handling in both directions
  • Comprehensive operator mapping with bidirectional support
  • Flat domain generation ensuring compatibility with OpenERP/Odoo
  • Semantic preservation of nested query structures with explicit operators when needed
  • Python 2.7 and 3.11 compatibility
  • Extensive test suite covering all domain structures including complex round-trip tests

This functionality mirrors the TypeScript implementation in gisce/ooquery-ts while ensuring correct OpenERP/Odoo domain format compliance and maintaining semantic accuracy for complex nested query structures.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

@ecarreras ecarreras changed the title [WIP] Em pots fer que pugui transformar un domini a JSON? Similar amb el que fem al repositori @gisce/ooquery-ts en el fitxer @gisce/ooquery-ts/files/src/convertFromDomain.ts [WIP] Convert domain to json Sep 2, 2025
Copilot AI and others added 2 commits September 2, 2025 11:39
Co-authored-by: ecarreras <294235+ecarreras@users.noreply.github.com>
Co-authored-by: ecarreras <294235+ecarreras@users.noreply.github.com>
Copilot AI changed the title [WIP] Convert domain to json Add domain to JSON conversion functionality Sep 2, 2025
Copilot AI requested a review from ecarreras September 2, 2025 11:42
@ecarreras

Copy link
Copy Markdown
Member

@copilot code should be compatible with py2.7 and py3.11

Co-authored-by: ecarreras <294235+ecarreras@users.noreply.github.com>

Copilot AI commented Sep 2, 2025

Copy link
Copy Markdown
Contributor Author

@copilot code should be compatible with py2.7 and py3.11

Fixed Python 2.7 compatibility by replacing f-strings with .format() method. The code now works with both Python 2.7 and Python 3.11 as requested. Changes made in commit 6ea34a9.

@ecarreras

Copy link
Copy Markdown
Member

@copilot the description of the pull-requests was better before, when you explain all the changes

Copilot AI commented Sep 2, 2025

Copy link
Copy Markdown
Contributor Author

@copilot the description of the pull-requests was better before, when you explain all the changes

Updated the PR description with detailed explanation of all changes made, including new files created, features implemented, technical details, usage examples, and testing coverage. The description now provides comprehensive information about the domain to JSON conversion functionality.

@ecarreras

Copy link
Copy Markdown
Member

@copilot can you add the same as https://github.com/gisce/ooquery-ts/blob/main/src/convertToDomain.ts to convert from json to openerp domain?

…sion

Co-authored-by: ecarreras <294235+ecarreras@users.noreply.github.com>

Copilot AI commented Sep 2, 2025

Copy link
Copy Markdown
Contributor Author

@copilot can you add the same as https://github.com/gisce/ooquery-ts/blob/main/src/convertToDomain.ts to convert from json to openerp domain?

I've implemented the convert_to_domain function that provides the same functionality as the TypeScript convertToDomain.ts. The implementation includes:

  • Converts JSON query structure back to OpenERP/Odoo domain arrays
  • Handles both AND (simple array) and OR (binary expression with prefix notation) combinators
  • Supports nested queries and all operator mappings
  • Special handling for 'in' operator with string values
  • Round-trip conversion consistency with the existing convert_from_domain function

The functionality is now available as convert_to_domain() and includes comprehensive tests and documentation. Changes made in commit e1bec8b.

Copilot AI changed the title Add domain to JSON conversion functionality Add bidirectional domain conversion functionality Sep 2, 2025
@ecarreras

Copy link
Copy Markdown
Member

@copilot conversion to domain is not correct, it can be nested... like ['|', ['|'... is a list of tuples or operators, and a one operator for two tuples

Co-authored-by: ecarreras <294235+ecarreras@users.noreply.github.com>

Copilot AI commented Sep 2, 2025

Copy link
Copy Markdown
Contributor Author

@copilot conversion to domain is not correct, it can be nested... like ['|', ['|'... is a list of tuples or operators, and a one operator for two tuples

Fixed the nested domain parsing issue in convert_from_domain function. The function now correctly handles nested domain structures like ['|', ['|', ('a', '=', 1), ('b', '=', 2)], ('c', '=', 3)] by properly detecting when a list element is a sub-domain versus a condition tuple and recursively parsing sub-domains. Changes implemented in commit 2ec1252.

Copilot AI changed the title Add bidirectional domain conversion functionality Add bidirectional domain conversion functionality with nested domain support Sep 2, 2025
Comment thread spec/domain_converter_spec.py
Comment thread spec/domain_converter_spec.py Outdated
Comment thread spec/domain_converter_spec.py Outdated
Comment thread spec/domain_converter_spec.py
…tructures

Co-authored-by: ecarreras <294235+ecarreras@users.noreply.github.com>
Copilot AI changed the title Add bidirectional domain conversion functionality with nested domain support Add bidirectional domain conversion with correct OpenERP/Odoo flat prefix notation Sep 3, 2025
Copilot AI requested a review from ecarreras September 3, 2025 06:12
@ecarreras

Copy link
Copy Markdown
Member

@copilot tests failling in roundtrip conversion, seems implicit & is lost?

…queries

Co-authored-by: ecarreras <294235+ecarreras@users.noreply.github.com>

Copilot AI commented Sep 3, 2025

Copy link
Copy Markdown
Contributor Author

@copilot tests failling in roundtrip conversion, seems implicit & is lost?

Fixed the roundtrip conversion issue. The problem was in how nested AND groups within OR queries were being handled. The implementation now correctly preserves explicit AND operators in nested query structures to maintain semantic accuracy.

For example, when converting a JSON structure with a nested AND group:

{
  "combinator": "or",
  "rules": [
    {"field": "name", "operator": "=", "value": "John"},
    {
      "combinator": "and",
      "rules": [
        {"field": "age", "operator": ">", "value": 18},
        {"field": "city", "operator": "=", "value": "Barcelona"}
      ]
    }
  ]
}

The domain now correctly includes explicit & operators: ['|', ('name', '=', 'John'), '&', ('age', '>', 18), ('city', '=', 'Barcelona')]

This ensures that roundtrip conversions preserve the original domain structure, including explicit AND operators. All tests now pass. Commit 13b04ab.

Copilot AI changed the title Add bidirectional domain conversion with correct OpenERP/Odoo flat prefix notation Add bidirectional domain conversion with correct OpenERP/Odoo flat prefix notation and semantic preservation Sep 3, 2025
@ecarreras ecarreras changed the title Add bidirectional domain conversion with correct OpenERP/Odoo flat prefix notation and semantic preservation Add bidirectional domain conversion with JSON Queries Sep 3, 2025
@ecarreras
ecarreras marked this pull request as ready for review September 3, 2025 06:30
@polsala
polsala merged commit 940da36 into master Sep 4, 2025
4 checks passed
@polsala
polsala deleted the copilot/fix-1f10535f-5a7b-426a-ba17-7eec97e375a3 branch September 4, 2025 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants