Skip to content

Convert non-SQLite sources to SQLite before merge#36

Draft
Copilot wants to merge 4 commits intomasterfrom
copilot/fix-sqlitemerger-non-sqlite-sources
Draft

Convert non-SQLite sources to SQLite before merge#36
Copilot wants to merge 4 commits intomasterfrom
copilot/fix-sqlitemerger-non-sqlite-sources

Conversation

Copy link
Contributor

Copilot AI commented Feb 12, 2026

SqliteMerger assumes source databases have scope_id attributes, causing AttributeError when merging MemUCIS (XML/YAML-loaded) databases. This blocks a common workflow: loading coverage from XML/YAML and merging into SQLite.

Changes

  • Auto-conversion layer in SqliteUCIS.merge(): Detects non-SQLite sources and converts them to temporary in-memory SQLite databases before passing to SqliteMerger
  • Conversion utilities:
    • _convert_to_sqlite() creates temporary SQLite DB from any UCIS type
    • _copy_scope_recursive() deep-copies scope hierarchy with coverage items
    • _copy_history_node() preserves test records and metadata
  • MemScope compatibility: Handles missing getFlags() implementation by accessing m_flags directly
  • Cleanup: Temporary databases auto-closed after merge

Usage

from ucis.mem.mem_ucis import MemUCIS
from ucis.sqlite.sqlite_ucis import SqliteUCIS

# Load from XML/YAML (returns MemUCIS)
mem_db = YamlReader().load("coverage.yaml")

# Merge into SQLite - now works transparently
sqlite_db = SqliteUCIS("merged.ucisdb")
sqlite_db.merge(mem_db)

The conversion is transparent - callers don't need to know whether the source is SQLite or in-memory.

Original prompt

This section details on the original issue you should resolve

<issue_title>SqliteMerger rejects non-SQLite source databases</issue_title>
<issue_description>
Testcase:

#!/usr/bin/env python3
"""
Issue 3 — `SqliteMerger` rejects non-SQLite source databases.

`SqliteUCIS.merge(source)` delegates to `SqliteMerger`, which accesses
`scope.scope_id` on the source.  When the source is a `MemUCIS`, its
scopes are `MemScope` objects that lack `scope_id`, causing:

    AttributeError: 'MemScope' object has no attribute 'scope_id'

This prevents merging XML/YAML-loaded (in-memory) databases into SQLite.

Reproduce:
    python tests/test_issue3_sqlite_merge_mem_source.py

Expected:  SqliteUCIS.merge(mem_db) merges coverage data successfully.
Actual:    AttributeError is raised.
"""

import os
import sys
import tempfile
import traceback


def create_sample_mem_db():
    """Return a small MemUCIS with one covergroup/coverpoint/bin."""
    from ucis.mem.mem_ucis import MemUCIS
    from ucis.source_info import SourceInfo
    from ucis.source_t import SourceT
    from ucis.scope_type_t import ScopeTypeT
    from ucis.cover_data import CoverData
    from ucis.cover_type_t import CoverTypeT
    from ucis.flags_t import FlagsT

    db = MemUCIS()
    fh = db.createFileHandle("test.sv", os.getcwd())
    si = SourceInfo(fh, 1, 0)
    du = db.createScope("tb", si, 1, SourceT.NONE, ScopeTypeT.DU_MODULE, FlagsT(
    inst = db.createInstance("tb", si, 1, SourceT.NONE,
                            ScopeTypeT.INSTANCE, du, FlagsT(0))
    cg = inst.createCovergroup("cg", si, 1, SourceT.NONE)
    cp = cg.createScope("cp", si, 1, SourceT.NONE, ScopeTypeT.COVERPOINT, FlagsT
    cd = CoverData(CoverTypeT.CVGBIN, 0)
    cd.data = 10
    cp.createNextCover("bin0", cd, si)
    return db


def test_sqlite_merge_from_mem():
    """SqliteUCIS.merge(MemUCIS) should succeed."""
    from ucis.sqlite.sqlite_ucis import SqliteUCIS

    src = create_sample_mem_db()

    with tempfile.NamedTemporaryFile(suffix=".ucisdb", delete=False) as f:
        dst_path = f.name

    try:
        dst = SqliteUCIS(dst_path)
        dst.merge(src)
        dst.close()
        print("PASS — SqliteUCIS.merge(MemUCIS) succeeded")
        return True
    except AttributeError as exc:
        if "scope_id" in str(exc):
            print("FAIL — Issue 3 reproduced:")
            traceback.print_exc()
            return False
        raise
    except Exception as exc:
        if "scope_id" in str(exc):
            print("FAIL — Issue 3 reproduced:")
            traceback.print_exc()
            return False
        raise
    finally:
        if os.path.exists(dst_path):
            os.remove(dst_path)


if __name__ == "__main__":
    ok = test_sqlite_merge_from_mem()
    sys.exit(0 if ok else 1)

```</issue_description>

<agent_instructions>This is a bit of an enhancement. When a memUCIS is passed to the SQLite merge, it must be converted to SQLite before merging. Create a unit test that covers this case. Enhance and ensure that this works</agent_instructions>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits February 12, 2026 20:46
Co-authored-by: mballance <1340805+mballance@users.noreply.github.com>
Co-authored-by: mballance <1340805+mballance@users.noreply.github.com>
…le metadata

Co-authored-by: mballance <1340805+mballance@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix SqliteMerger to accept non-SQLite source databases Convert non-SQLite sources to SQLite before merge Feb 12, 2026
Copilot AI requested a review from mballance February 12, 2026 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SqliteMerger rejects non-SQLite source databases

2 participants