github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/vvm/engines/impl.go (about)

     1  /*
     2   * Copyright (c) 2021-present Sigma-Soft, Ltd.
     3   * @author: Nikolay Nikitin
     4   */
     5  
     6  package engines
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  
    12  	"github.com/voedger/voedger/pkg/appdef"
    13  	"github.com/voedger/voedger/pkg/iextengine"
    14  	"github.com/voedger/voedger/pkg/istructs"
    15  	"github.com/voedger/voedger/pkg/istructsmem"
    16  )
    17  
    18  // provides all built-in extension functions for specified application config
    19  //
    20  // # Panics:
    21  //   - if any extension implementation not found
    22  //   - if any extension package full path is unknown
    23  func provideAppsBuiltInExtFuncs(cfgs istructsmem.AppConfigsType) iextengine.BuiltInExtFuncs {
    24  	funcs := make(iextengine.BuiltInExtFuncs)
    25  
    26  	for app, cfg := range cfgs {
    27  		appFuncs := make(iextengine.BuiltInAppExtFuncs)
    28  		cfg.AppDef.Extensions(
    29  			func(ext appdef.IExtension) {
    30  				if ext.Engine() != appdef.ExtensionEngineKind_BuiltIn {
    31  					return
    32  				}
    33  				name := ext.QName()
    34  
    35  				var fn iextengine.BuiltInExtFunc
    36  
    37  				switch ext.Kind() {
    38  				case appdef.TypeKind_Command:
    39  					if cmd, ok := cfg.Resources.QueryResource(name).(istructs.ICommandFunction); ok {
    40  						fn = func(_ context.Context, io iextengine.IExtensionIO) error {
    41  							return cmd.Exec(istructs.ExecCommandArgs{State: io, Intents: io})
    42  						}
    43  					}
    44  				case appdef.TypeKind_Query:
    45  					if query, ok := cfg.Resources.QueryResource(name).(istructs.IQueryFunction); ok {
    46  						fn = func(ctx context.Context, io iextengine.IExtensionIO) error {
    47  							return query.Exec(
    48  								ctx,
    49  								istructs.ExecQueryArgs{State: io},
    50  								// TODO: add query result handler
    51  								func(istructs.IObject) error { return nil },
    52  							)
    53  						}
    54  					}
    55  				case appdef.TypeKind_Projector:
    56  					var prj istructs.Projector
    57  					if ext.(appdef.IProjector).Sync() {
    58  						prj = cfg.SyncProjectors()[name]
    59  					} else {
    60  						prj = cfg.AsyncProjectors()[name]
    61  					}
    62  					if prj.Name != appdef.NullQName {
    63  						fn = func(_ context.Context, io iextengine.IExtensionIO) error {
    64  							return prj.Func(io.PLogEvent(), io, io)
    65  						}
    66  					}
    67  				}
    68  
    69  				if fn == nil {
    70  					panic(fmt.Errorf("application «%v»: %v implementation not found", app, ext))
    71  				}
    72  
    73  				extName := cfg.AppDef.FullQName(name)
    74  				if extName == appdef.NullFullQName {
    75  					panic(fmt.Errorf("application «%v»: package «%s» full path is unknown", app, name.Pkg()))
    76  				}
    77  
    78  				appFuncs[extName] = fn
    79  			})
    80  
    81  		funcs[app] = appFuncs
    82  	}
    83  	return funcs
    84  }