// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com) // All rights reserved. // BaseArea provides default implementations for the Area interface. // Harbour equivalent: WAAREA (workarea.c) — ~25 real + ~76 stub methods. // Concrete drivers (DBFArea, etc.) embed BaseArea and override as needed. package hbrdd import "five/hbrt" // BaseArea is the base workarea with default flag management. // Harbour: struct _AREA in hbapirdd.h type BaseArea struct { driver Driver alias string fields []FieldInfo fieldMap map[string]int // field name → index (0-based) // Cursor state flags — Harbour: fBof, fEof, fFound, fTop, fBottom FBof bool FEof bool FFound bool FTop bool FBottom bool // Filter filterExpr string filterBlock func(*hbrt.Thread) bool // Locate locateExpr string locateBlock func(*hbrt.Thread) bool // Relations relations []*Relation } // Relation holds a parent→child relationship. type Relation struct { Child Area KeyExpr func(*hbrt.Thread) hbrt.Value Scoped bool } // --- BaseArea default implementations --- func (a *BaseArea) Driver() Driver { return a.driver } func (a *BaseArea) Alias() string { return a.alias } func (a *BaseArea) SetAlias(s string) { a.alias = s } func (a *BaseArea) BOF() bool { return a.FBof } func (a *BaseArea) EOF() bool { return a.FEof } func (a *BaseArea) Found() bool { return a.FFound } func (a *BaseArea) SetFound(b bool) { a.FFound = b } func (a *BaseArea) FieldCount() int { return len(a.fields) } func (a *BaseArea) GetFieldInfo(index int) FieldInfo { if index >= 0 && index < len(a.fields) { return a.fields[index] } return FieldInfo{} } // FieldIndex returns the 0-based field index by name, or -1 if not found. func (a *BaseArea) FieldIndex(name string) int { if a.fieldMap == nil { return -1 } if idx, ok := a.fieldMap[name]; ok { return idx } return -1 } // InitFields sets up the field array and name→index map. func (a *BaseArea) InitFields(fields []FieldInfo) { a.fields = fields a.fieldMap = make(map[string]int, len(fields)) for i, f := range fields { a.fieldMap[f.Name] = i } } // Close provides the base close behavior (reset flags). // Harbour: hb_waClose func (a *BaseArea) Close() error { a.FBof = true a.FEof = true a.FFound = false a.fields = nil a.fieldMap = nil a.relations = nil return nil } // --- Filter support --- func (a *BaseArea) SetFilter(expr string, block func(*hbrt.Thread) bool) error { a.filterExpr = expr a.filterBlock = block return nil } func (a *BaseArea) ClearFilter() error { a.filterExpr = "" a.filterBlock = nil return nil } func (a *BaseArea) HasFilter() bool { return a.filterBlock != nil } // --- Relation support --- func (a *BaseArea) SetRelation(child Area, keyExpr func(*hbrt.Thread) hbrt.Value, scoped bool) error { a.relations = append(a.relations, &Relation{ Child: child, KeyExpr: keyExpr, Scoped: scoped, }) return nil } func (a *BaseArea) ClearRelation() error { a.relations = nil return nil } // --- Locate support --- func (a *BaseArea) SetLocate(expr string, block func(*hbrt.Thread) bool) { a.locateExpr = expr a.locateBlock = block } func (a *BaseArea) LocateBlock() func(*hbrt.Thread) bool { return a.locateBlock } // --- Global RDD configuration callbacks --- // These are set by hbrtl to avoid circular imports. var ( // IsSetDeleted returns true when SET DELETED is ON. // Set by hbrtl.init() to hbrtl.GetSetDeleted. IsSetDeleted func() bool )