Files
five/hbrdd/base.go
Charles KWON OhJun 486e466592 feat: FiveSql2 43/43, @byref, mutable closure, RTL 479, DateTime fix
Major changes since last commit:
- FiveSql2 SQL:1999 engine (10,458 LOC) — 43/43 ALL PASS
- 21 compiler/runtime bugs fixed (short-circuit AND/OR, FOR LOOP, etc.)
- @byref pass-by-reference via RefCell pattern
- Mutable closure capture (EnsureLocalRef + RefCell sharing)
- RTL: 400 → 479 functions (+79: file, string, datetime, hash, UTF-8)
- DateTime/Timestamp fully working (hb_DateTime, hb_Hour/Min/Sec, display)
- Reserved word guard (39 keywords blocked from function calls)
- AEval arg order fix (element before index)
- Closure capture redecl fix (unique _cap_ names per block)
- Hash/string indexing in ArrayPush/ArrayPop
- Harbour compat test suite: 51/51
- 4 docs: Porting Report, Implementation Plan, Optimization Plan, Commercialization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:35:37 +09:00

148 lines
3.4 KiB
Go

// 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
)