enhanced and simplified Reset(), Clean() and Next() methods
This commit is contained in:
		
							parent
							
								
									d6bf5ee500
								
							
						
					
					
						commit
						ad3c1e5a60
					
				
							
								
								
									
										213
									
								
								data-cursor.go
									
									
									
									
									
								
							
							
						
						
									
										213
									
								
								data-cursor.go
									
									
									
									
									
								
							| @ -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) | ||||
| 		} | ||||
| 		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) | ||||
| 		ctx := cloneContext(dc.ctx) | ||||
| 		actualParams := bindActualParams(dc.resetFunc, []any{dc.resource}) | ||||
| 		_, err = dc.resetFunc.InvokeNamed(ctx, ResetName, actualParams) | ||||
| 		exportObjects(dc.ctx, ctx) | ||||
| 	} | ||||
| 	success = err == nil | ||||
| 	dc.index = -1 | ||||
| 	dc.count = 0 | ||||
| 	dc.initState = true | ||||
| 	dc.current = nil | ||||
| 	dc.lastErr = 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) | ||||
| 		ctx := cloneContext(dc.ctx) | ||||
| 		actualParams := bindActualParams(dc.cleanFunc, []any{dc.resource}) | ||||
| 		_, err = dc.cleanFunc.InvokeNamed(ctx, CleanName, actualParams) | ||||
| 		exportObjects(dc.ctx, ctx) | ||||
| 	} | ||||
| 	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,46 +213,89 @@ 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 | ||||
| 		for item == nil && dc.lastErr == nil { | ||||
| 			ctx := cloneContext(dc.ctx) | ||||
| 			dc.index++ | ||||
| 	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) | ||||
| 		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() | ||||
| 		exportObjects(dc.ctx, ctx) | ||||
| 	} | ||||
| 	dc.current = item | ||||
| 	if dc.lastErr != nil { | ||||
| 		dc.index-- | ||||
| 		dc.Clean() | ||||
| 	} | ||||
| 	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 | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user