github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/sys/workspace/impl_childworkspace.go (about)

     1  /*
     2   * Copyright (c) 2020-present unTill Pro, Ltd.
     3   */
     4  
     5  package workspace
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"net/http"
    11  
    12  	"github.com/voedger/voedger/pkg/appdef"
    13  	"github.com/voedger/voedger/pkg/goutils/iterate"
    14  	"github.com/voedger/voedger/pkg/istructs"
    15  	"github.com/voedger/voedger/pkg/istructsmem"
    16  	"github.com/voedger/voedger/pkg/state"
    17  	"github.com/voedger/voedger/pkg/sys/authnz"
    18  	coreutils "github.com/voedger/voedger/pkg/utils"
    19  )
    20  
    21  func provideExecCmdInitChildWorkspace(appDef appdef.IAppDef) istructsmem.ExecCommandClosure {
    22  	return func(args istructs.ExecCommandArgs) (err error) {
    23  		wsName := args.ArgumentObject.AsString(authnz.Field_WSName)
    24  		kb, err := args.State.KeyBuilder(state.View, QNameViewChildWorkspaceIdx)
    25  		if err != nil {
    26  			return
    27  		}
    28  		kb.PutInt32(field_dummy, 1)
    29  		kb.PutString(authnz.Field_WSName, wsName)
    30  		_, ok, err := args.State.CanExist(kb)
    31  		if err != nil {
    32  			return
    33  		}
    34  
    35  		if ok {
    36  			return coreutils.NewHTTPErrorf(http.StatusConflict, fmt.Sprintf("child workspace with name %s already exists", wsName))
    37  		}
    38  
    39  		wsKind := args.ArgumentObject.AsQName(authnz.Field_WSKind)
    40  		if appDef.WorkspaceByDescriptor(wsKind) == nil {
    41  			return coreutils.NewHTTPErrorf(http.StatusBadRequest, fmt.Sprintf("provided WSKind %s is not a QName of a workspace descriptor", wsKind))
    42  		}
    43  
    44  		wsKindInitializationData := args.ArgumentObject.AsString(authnz.Field_WSKindInitializationData)
    45  		templateName := args.ArgumentObject.AsString(field_TemplateName)
    46  		wsClusterID := args.ArgumentObject.AsInt32(authnz.Field_WSClusterID)
    47  		templateParams := args.ArgumentObject.AsString(Field_TemplateParams)
    48  
    49  		// Create cdoc.sys.ChildWorkspace
    50  		kb, err = args.State.KeyBuilder(state.Record, authnz.QNameCDocChildWorkspace)
    51  		if err != nil {
    52  			return
    53  		}
    54  		cdocChildWS, err := args.Intents.NewValue(kb)
    55  		if err != nil {
    56  			return
    57  		}
    58  		cdocChildWS.PutRecordID(appdef.SystemField_ID, 1)
    59  		cdocChildWS.PutString(authnz.Field_WSName, wsName)
    60  		cdocChildWS.PutQName(authnz.Field_WSKind, wsKind)
    61  		cdocChildWS.PutString(authnz.Field_WSKindInitializationData, wsKindInitializationData)
    62  		cdocChildWS.PutString(field_TemplateName, templateName)
    63  		cdocChildWS.PutInt32(authnz.Field_WSClusterID, wsClusterID)
    64  		cdocChildWS.PutString(Field_TemplateParams, templateParams)
    65  
    66  		return err
    67  	}
    68  }
    69  
    70  var childWorkspaceIdxProjector = func(event istructs.IPLogEvent, s istructs.IState, intents istructs.IIntents) (err error) {
    71  	return iterate.ForEachError(event.CUDs, func(rec istructs.ICUDRow) error {
    72  		if rec.QName() != authnz.QNameCDocChildWorkspace || !rec.IsNew() {
    73  			return nil
    74  		}
    75  
    76  		kb, err := s.KeyBuilder(state.View, QNameViewChildWorkspaceIdx)
    77  		if err != nil {
    78  			return err
    79  		}
    80  		kb.PutInt32(field_dummy, 1)
    81  		wsName := rec.AsString(authnz.Field_WSName)
    82  		kb.PutString(authnz.Field_WSName, wsName)
    83  
    84  		vb, err := intents.NewValue(kb)
    85  		if err != nil {
    86  			return err
    87  		}
    88  		vb.PutInt64(Field_ChildWorkspaceID, int64(rec.ID()))
    89  		return nil
    90  	})
    91  }
    92  
    93  // targetApp/parentWSID/q.sys.QueryChildWorkspaceByName
    94  func qcwbnQryExec(_ context.Context, args istructs.ExecQueryArgs, callback istructs.ExecQueryCallback) error {
    95  	wsName := args.ArgumentObject.AsString(authnz.Field_WSName)
    96  	kb, err := args.State.KeyBuilder(state.View, QNameViewChildWorkspaceIdx)
    97  	if err != nil {
    98  		return err
    99  	}
   100  	kb.PutInt32(field_dummy, 1)
   101  	kb.PutString(authnz.Field_WSName, wsName)
   102  	childWSIdx, ok, err := args.State.CanExist(kb)
   103  	if err != nil {
   104  		return err
   105  	}
   106  	if !ok {
   107  		return coreutils.NewHTTPErrorf(http.StatusNotFound, "child workspace ", wsName, " not found")
   108  	}
   109  	kb, err = args.State.KeyBuilder(state.Record, appdef.NullQName)
   110  	if err != nil {
   111  		return err
   112  	}
   113  	kb.PutRecordID(state.Field_ID, istructs.RecordID(childWSIdx.AsInt64(Field_ChildWorkspaceID)))
   114  	rec, err := args.State.MustExist(kb)
   115  	if err != nil {
   116  		return err
   117  	}
   118  	return callback(&qcwbnRR{
   119  		wsName:                   rec.AsString(authnz.Field_WSName),
   120  		wsKind:                   rec.AsQName(authnz.Field_WSKind),
   121  		wsKindInitializationData: rec.AsString(authnz.Field_WSKindInitializationData),
   122  		templateName:             rec.AsString(field_TemplateName),
   123  		templateParams:           rec.AsString(Field_TemplateParams),
   124  		wsid:                     rec.AsInt64(authnz.Field_WSID),
   125  		wsError:                  rec.AsString(authnz.Field_WSError),
   126  	})
   127  }
   128  
   129  // q.sys.QueryChildWorkspaceByName
   130  type qcwbnRR struct {
   131  	istructs.NullObject
   132  	wsName                   string
   133  	wsKind                   appdef.QName
   134  	wsKindInitializationData string
   135  	templateName             string
   136  	templateParams           string
   137  	wsid                     int64
   138  	wsError                  string
   139  }
   140  
   141  func (q *qcwbnRR) AsInt64(string) int64 { return q.wsid }
   142  func (q *qcwbnRR) AsString(name string) string {
   143  	switch name {
   144  	case authnz.Field_WSName:
   145  		return q.wsName
   146  	case authnz.Field_WSKindInitializationData:
   147  		return q.wsKindInitializationData
   148  	case field_TemplateName:
   149  		return q.templateName
   150  	case authnz.Field_WSError:
   151  		return q.wsError
   152  	case authnz.Field_WSKind:
   153  		return q.wsKind.String()
   154  	case Field_TemplateParams:
   155  		return q.templateParams
   156  	default:
   157  		panic("unexpected field to return: " + name)
   158  	}
   159  }