enhanced and simplified Reset(), Clean() and Next() methods

This commit is contained in:
Celestino Amoroso 2024-09-09 15:23:07 +02:00
parent d6bf5ee500
commit ad3c1e5a60

View File

@ -6,12 +6,14 @@ package expr
import (
"io"
"slices"
)
type dataCursor struct {
ds map[string]Functor
ctx ExprContext
initState bool // true if no item has prodiced yet (this replace di initial Next() call in the contructor)
initState bool // true if no item has produced yet (this replace di initial Next() call in the contructor)
// cursorValid bool // true if resource is nil or if clean has not yet been called
index int
count int
current any
@ -26,6 +28,7 @@ func NewDataCursor(ctx ExprContext, ds map[string]Functor, resource any) (dc *da
dc = &dataCursor{
ds: ds,
initState: true,
// cursorValid: true,
index: -1,
count: 0,
current: nil,
@ -36,7 +39,6 @@ func NewDataCursor(ctx ExprContext, ds map[string]Functor, resource any) (dc *da
cleanFunc: ds[CleanName],
resetFunc: ds[ResetName],
}
//dc.Next()
return
}
@ -77,7 +79,7 @@ func (dc *dataCursor) String() string {
}
func (dc *dataCursor) HasOperation(name string) (exists bool) {
exists = name == IndexName
exists = slices.Contains([]string{CleanName, ResetName, CurrentName, IndexName}, name)
if !exists {
f, ok := dc.ds[name]
exists = ok && isFunctor(f)
@ -88,63 +90,83 @@ func (dc *dataCursor) HasOperation(name string) (exists bool) {
func (dc *dataCursor) CallOperation(name string, args map[string]any) (value any, err error) {
if name == IndexName {
value = int64(dc.Index())
} else if name == CleanName {
err = dc.Clean()
} else if name == ResetName {
err = dc.Reset()
} else if functor, ok := dc.ds[name]; ok && isFunctor(functor) {
if functor == dc.cleanFunc {
value, err = dc.Clean()
} else if functor == dc.resetFunc {
value, err = dc.Reset()
} else {
ctx := cloneContext(dc.ctx)
value, err = functor.InvokeNamed(ctx, name, args)
exportObjects(dc.ctx, ctx)
}
} else {
err = errNoOperation(name)
}
return
}
func (dc *dataCursor) Reset() (success bool, err error) {
// func (dc *dataCursor) Reset() (err error) {
// if dc.resetFunc != nil {
// if dc.resource != nil {
// ctx := cloneContext(dc.ctx)
// actualParams := bindActualParams(dc.resetFunc, []any{dc.resource})
// _, err = dc.resetFunc.InvokeNamed(ctx, ResetName, actualParams)
// exportObjects(dc.ctx, ctx)
// dc.index = -1
// dc.count = 0
// dc.initState = true
// dc.current = nil
// dc.lastErr = nil
// } else {
// err = errInvalidDataSource()
// }
// } else {
// err = errNoOperation(ResetName)
// }
// return
// }
func (dc *dataCursor) Reset() (err error) {
if dc.resetFunc != nil {
if dc.resource != nil {
ctx := cloneContext(dc.ctx)
actualParams := bindActualParams(dc.resetFunc, []any{dc.resource})
_, err = dc.resetFunc.InvokeNamed(ctx, ResetName, actualParams)
exportObjects(dc.ctx, ctx)
}
dc.index = -1
dc.count = 0
dc.initState = true
dc.current = nil
dc.lastErr = nil
//dc.Next()
} else {
err = errInvalidDataSource()
}
} else {
err = errNoOperation(ResetName)
}
success = err == nil
return
}
func (dc *dataCursor) Clean() (success bool, err error) {
func (dc *dataCursor) Clean() (err error) {
if dc.cleanFunc != nil {
if dc.resource != nil {
ctx := cloneContext(dc.ctx)
actualParams := bindActualParams(dc.cleanFunc, []any{dc.resource})
_, err = dc.cleanFunc.InvokeNamed(ctx, CleanName, actualParams)
// dc.resource = nil
exportObjects(dc.ctx, ctx)
} else {
err = errInvalidDataSource()
}
} else {
err = errNoOperation(CleanName)
}
success = err == nil
dc.lastErr = io.EOF
return
}
// func (dc *dataCursor) Clean() (err error) {
// if dc.cleanFunc != nil {
// if dc.resource != nil {
// ctx := cloneContext(dc.ctx)
// actualParams := bindActualParams(dc.cleanFunc, []any{dc.resource})
// _, err = dc.cleanFunc.InvokeNamed(ctx, CleanName, actualParams)
// exportObjects(dc.ctx, ctx)
// } else {
// err = errInvalidDataSource()
// }
// } else {
// err = errNoOperation(CleanName)
// }
// return
// }
func (dc *dataCursor) Current() (item any, err error) { // must return io.EOF at the last item
dc.init()
@ -191,7 +213,6 @@ func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF af
return
}
current = dc.current
if dc.resource != nil {
filter := dc.ds[FilterName]
mapper := dc.ds[MapName]
var item any
@ -225,12 +246,56 @@ func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF af
dc.index--
dc.Clean()
}
} else {
dc.lastErr = errInvalidDataSource()
}
return
}
// func (dc *dataCursor) Next() (current any, err error) { // must return io.EOF after the last item
// if dc.initState {
// dc.init()
// } else if err = dc.lastErr; err != nil {
// return
// }
// current = dc.current
// if dc.resource != nil {
// filter := dc.ds[FilterName]
// mapper := dc.ds[MapName]
// var item any
// for item == nil && dc.lastErr == nil {
// ctx := cloneContext(dc.ctx)
// dc.index++
// actualParams := bindActualParams(dc.nextFunc, []any{dc.resource, dc.index})
// if item, dc.lastErr = dc.nextFunc.InvokeNamed(ctx, NextName, actualParams); dc.lastErr == nil {
// if item == nil {
// dc.lastErr = io.EOF
// } else {
// accepted := true
// if filter != nil {
// if accepted, dc.lastErr = dc.checkFilter(filter, item); dc.lastErr != nil || !accepted {
// item = nil
// }
// }
// if accepted {
// dc.count++
// }
// if item != nil && mapper != nil {
// item, dc.lastErr = dc.mapItem(mapper, item)
// }
// }
// }
// exportObjects(dc.ctx, ctx)
// }
// dc.current = item
// if dc.lastErr != nil {
// dc.index--
// dc.Clean()
// }
// } else {
// dc.lastErr = errInvalidDataSource()
// }
// return
// }
func (dc *dataCursor) Index() int {
return dc.index - 1
}