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 }