semantic

package
v0.18.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 5 Imported by: 0

README

semantic

A pure resolver that maps physical columns (source + collection + scanned column list) to the entity fields a project's model says they mean, per REQ:field-mapping-model in datatug/datatug's core-investigation-loop feature spec: declared EntityField.Mappings win; absent a declared mapping, EntityField.NamePatterns are tried and the result is labelled inferred; a column matching neither is simply absent from the result.

No I/O, no mutation of its inputs — safe to call from datatug-cli's HTTP resolver, the TUI, or a future datatug context verb.

Example

entities := []*datatug.Entity{
	{
		ProjectItem: datatug.ProjectItem{ProjItemBrief: datatug.ProjItemBrief{ID: "customer"}},
		Fields: datatug.EntityFields{
			{
				ID: "id", Type: "string",
				Mappings: datatug.PhysicalRefs{
					{Source: "chinook", Collection: "Customer", Column: "CustomerId"},
				},
			},
			{
				ID: "email", Type: "string",
				NamePatterns: datatug.StringPatterns{{Type: "exact", Value: "Email"}},
			},
		},
	},
}

results := semantic.Resolve(entities, "chinook", "Customer", []semantic.Column{
	{Name: "CustomerId", Type: "int"},
	{Name: "Email", Type: "string"},
	{Name: "FirstName", Type: "string"},
})
// results == []semantic.Resolution{
//   {Column: "CustomerId", Entity: "customer", Field: "id", Provenance: semantic.Declared},
//   {Column: "Email", Entity: "customer", Field: "email", Provenance: semantic.Inferred, Rule: "namePattern:exact:Email"},
// }
// "FirstName" matches neither a declared mapping nor a name pattern, so it
// has no entry at all.

Documentation

Overview

Package semantic resolves physical columns (a source + collection + set of scanned columns) to the entity fields a project's model says they mean.

Resolve is pure - no I/O, no mutation - so it can be called from anywhere that already has a project's entities in memory: the datatug-cli HTTP resolver behind GET /datatug/semantic/columns (REQ:semantic-resolution-endpoint in datatug/datatug's core-investigation-loop feature), the TUI, or a future `datatug context` verb. Placement note: the resolver lives here in datatug-core rather than in datatug-cli/pkg/semantic (as sketched in the Phase-1 plan's task 5) because datatug-cli currently vendors its own copy of this package's types and a separate stream is restoring its module dependency; the HTTP endpoint itself is still wired in datatug-cli. This is a planner decision, not a founder ruling - open to being moved once the module dependency lands.

Declared EntityField.Mappings always win over an EntityField.NamePatterns match; NamePatterns are tried only for a column with no declared mapping anywhere in the project, and the result is labelled Inferred. See Resolve for the full tie-break rule when more than one field could claim the same column.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Column

type Column struct {
	Name string
	Type string
}

Column is a single physical column to resolve against a project's entities.

type Provenance

type Provenance string

Provenance identifies how a Resolution was determined.

const (
	// Declared means the column matched an EntityField's declared Mappings.
	Declared Provenance = "declared"
	// Inferred means the column matched an EntityField's NamePatterns, with
	// no declared mapping present for it.
	Inferred Provenance = "inferred"
)

type Resolution

type Resolution struct {
	Column     string
	Entity     string
	Field      string
	Provenance Provenance
	// Rule documents how the winner was chosen: which name pattern matched
	// (for Inferred), and/or a tie-break note when more than one field
	// resolved the same column at the same provenance level.
	Rule string
	// Err is set only when the column had NamePatterns candidates that could
	// not be evaluated (e.g. an invalid regexp) and neither a declared
	// mapping nor a valid inferred candidate resolved it. When Err is set,
	// Entity, Field, Provenance and Rule are zero.
	Err error
}

Resolution is what one Column resolved to.

func Resolve

func Resolve(entities []*datatug.Entity, source, collection string, columns []Column) []Resolution

Resolve returns, for each Column, the entity field it maps to in the given source/collection (table): declared EntityField.Mappings win; absent a declared mapping, EntityField.NamePatterns are tried; a column matching neither is simply absent from the result (see REQ:field-mapping-model in datatug/datatug's core-investigation-loop feature).

When more than one field resolves the same column at the same provenance level, the field belonging to the lowest Entity.ID wins (Entity.ID, then EntityField.ID, ascending) and the tie is recorded in the winning Resolution's Rule. This keeps Resolve deterministic without requiring callers to pre-sort entities.

Resolve is pure: it performs no I/O and does not mutate entities. It never panics - a pattern that fails to evaluate (e.g. invalid regexp syntax) yields a Resolution with Err set instead, unless a declared mapping or another, valid pattern already resolved the column.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL