descr

package
v1.202405300917.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2024 License: MIT Imports: 5 Imported by: 0

README

Packages and Definitions Description

Json-oriented structures to describe application packages, types, views, functions, rate limits, etc.

Documentation

Overview

Example
/*
 * Copyright (c) 2021-present Sigma-Soft, Ltd.
 * @author: Nikolay Nikitin
 */

package main

import (
	"encoding/json"
	"fmt"

	"github.com/stretchr/testify/mock"
	"github.com/voedger/voedger/pkg/appdef"
	"github.com/voedger/voedger/pkg/istructs"
	"github.com/voedger/voedger/pkg/istructsmem/internal/descr"
)

func main() {
	appDef := func() appdef.IAppDef {
		adb := appdef.New()
		adb.AddPackage("test", "test/path")

		numName := appdef.NewQName("test", "number")
		strName := appdef.NewQName("test", "string")

		sysRecords := appdef.NewQName("sys", "records")
		sysViews := appdef.NewQName("sys", "views")

		docName, recName := appdef.NewQName("test", "doc"), appdef.NewQName("test", "rec")

		n := adb.AddData(numName, appdef.DataKind_int64, appdef.NullQName, appdef.MinIncl(1))
		n.SetComment("natural (positive) integer")

		s := adb.AddData(strName, appdef.DataKind_string, appdef.NullQName)
		s.AddConstraints(appdef.MinLen(1), appdef.MaxLen(100), appdef.Pattern(`^\w+$`, "only word characters allowed"))

		doc := adb.AddCDoc(docName)
		doc.SetSingleton()
		doc.
			AddField("f1", appdef.DataKind_int64, true).
			SetFieldComment("f1", "field comment").
			AddField("f2", appdef.DataKind_string, false, appdef.MinLen(4), appdef.MaxLen(4), appdef.Pattern(`^\w+$`)).
			AddDataField("numField", numName, false).
			AddRefField("mainChild", false, recName)
		doc.AddContainer("rec", recName, 0, 100, "container comment")
		doc.AddUnique(appdef.UniqueQName(docName, "unique1"), []appdef.FieldName{"f1", "f2"})
		doc.SetComment(`comment 1`, `comment 2`)

		rec := adb.AddCRecord(recName)
		rec.
			AddField("f1", appdef.DataKind_int64, true).
			AddField("f2", appdef.DataKind_string, false).
			AddField("phone", appdef.DataKind_string, true, appdef.MinLen(1), appdef.MaxLen(25)).
			SetFieldVerify("phone", appdef.VerificationKind_Any...)
		rec.
			SetUniqueField("phone").
			AddUnique(appdef.UniqueQName(recName, "uniq1"), []appdef.FieldName{"f1"})

		viewName := appdef.NewQName("test", "view")
		view := adb.AddView(viewName)
		view.Key().PartKey().
			AddField("pk_1", appdef.DataKind_int64)
		view.Key().ClustCols().
			AddField("cc_1", appdef.DataKind_string, appdef.MaxLen(100))
		view.Value().
			AddDataField("vv_code", strName, true).
			AddRefField("vv_1", true, docName)

		objName := appdef.NewQName("test", "obj")
		obj := adb.AddObject(objName)
		obj.AddField("f1", appdef.DataKind_string, true)

		cmdName := appdef.NewQName("test", "cmd")
		adb.AddCommand(cmdName).
			SetUnloggedParam(objName).
			SetParam(objName).
			SetEngine(appdef.ExtensionEngineKind_WASM)

		queryName := appdef.NewQName("test", "query")
		adb.AddQuery(queryName).
			SetParam(objName).
			SetResult(appdef.QNameANY)

		prj := adb.AddProjector(appdef.NewQName("test", "projector"))
		prj.
			SetWantErrors().
			SetEngine(appdef.ExtensionEngineKind_WASM)
		prj.Events().
			Add(recName, appdef.ProjectorEventKind_AnyChanges...).SetComment(recName, "run projector every time when «test.rec» is changed").
			Add(cmdName).SetComment(cmdName, "run projector every time when «test.cmd» command is executed").
			Add(objName).SetComment(objName, "run projector every time when any command with «test.obj» argument is executed")
		prj.States().
			Add(sysRecords, docName, recName).SetComment(sysRecords, "needs to read «test.doc» and «test.rec» from «sys.records» storage")
		prj.Intents().
			Add(sysViews, viewName).SetComment(sysViews, "needs to update «test.view» from «sys.views» storage")

		reader := adb.AddRole(appdef.NewQName("test", "reader"))
		reader.SetComment("read-only role")
		reader.Grant(
			[]appdef.PrivilegeKind{appdef.PrivilegeKind_Select},
			[]appdef.QName{docName, recName}, []appdef.FieldName{"f1", "f2"},
			"allow reader to select some fields from test.doc and test.rec")
		reader.Grant(
			[]appdef.PrivilegeKind{appdef.PrivilegeKind_Select},
			[]appdef.QName{viewName}, nil,
			"allow reader to select all fields from test.view")
		reader.GrantAll([]appdef.QName{queryName}, "allow reader to execute test.query")

		writer := adb.AddRole(appdef.NewQName("test", "writer"))
		writer.SetComment("read-write role")
		writer.GrantAll([]appdef.QName{docName, recName, viewName}, "allow writer to do anything with test.doc, test.rec and test.view")
		writer.Revoke(
			[]appdef.PrivilegeKind{appdef.PrivilegeKind_Update},
			[]appdef.QName{docName},
			"disable writer to update test.doc")
		writer.GrantAll([]appdef.QName{cmdName, queryName}, "allow writer to execute all test functions")

		app, err := adb.Build()
		if err != nil {
			panic(err)
		}

		return app
	}()

	res := &mockResources{}
	res.
		On("Resources", mock.AnythingOfType("func(appdef.QName)")).Run(func(args mock.Arguments) {})

	appStr := &mockedAppStructs{}
	appStr.
		On("AppQName").Return(istructs.AppQName_test1_app1).
		On("AppDef").Return(appDef).
		On("Resources").Return(res)

	appLimits := map[appdef.QName]map[istructs.RateLimitKind]istructs.RateLimit{}

	app := descr.Provide(appStr, appLimits)

	json, err := json.MarshalIndent(app, "", "  ")

	fmt.Println("error:", err)
	fmt.Println(string(json))

	//os.WriteFile("C://temp//provide_test.json", json, 0644)

}

type mockedAppStructs struct {
	istructs.IAppStructs
	mock.Mock
}

func (s *mockedAppStructs) AppDef() appdef.IAppDef {
	return s.Called().Get(0).(appdef.IAppDef)
}

func (s *mockedAppStructs) AppQName() istructs.AppQName {
	return s.Called().Get(0).(istructs.AppQName)
}

func (s *mockedAppStructs) Resources() istructs.IResources {
	return s.Called().Get(0).(istructs.IResources)
}

type mockResources struct {
	istructs.IResources
	mock.Mock
}

func (r *mockResources) Resources(cb func(appdef.QName)) {
	r.Called(cb)
}
Output:

error: <nil>
{
  "Name": "test1/app1",
  "Packages": {
    "test": {
      "Path": "test/path",
      "DataTypes": {
        "test.number": {
          "Comment": "natural (positive) integer",
          "Ancestor": "sys.int64",
          "Constraints": {
            "MinIncl": 1
          }
        },
        "test.string": {
          "Ancestor": "sys.string",
          "Constraints": {
            "MaxLen": 100,
            "MinLen": 1,
            "Pattern": "^\\w+$"
          }
        }
      },
      "Structures": {
        "test.doc": {
          "Comment": "comment 1\ncomment 2",
          "Kind": "CDoc",
          "Fields": [
            {
              "Name": "sys.QName",
              "Data": "sys.QName",
              "Required": true
            },
            {
              "Name": "sys.ID",
              "Data": "sys.RecordID",
              "Required": true
            },
            {
              "Name": "sys.IsActive",
              "Data": "sys.bool"
            },
            {
              "Comment": "field comment",
              "Name": "f1",
              "Data": "sys.int64",
              "Required": true
            },
            {
              "Name": "f2",
              "DataType": {
                "Ancestor": "sys.string",
                "Constraints": {
                  "MaxLen": 4,
                  "MinLen": 4,
                  "Pattern": "^\\w+$"
                }
              }
            },
            {
              "Name": "numField",
              "Data": "test.number"
            },
            {
              "Name": "mainChild",
              "Data": "sys.RecordID",
              "Refs": [
                "test.rec"
              ]
            }
          ],
          "Containers": [
            {
              "Comment": "container comment",
              "Name": "rec",
              "Type": "test.rec",
              "MinOccurs": 0,
              "MaxOccurs": 100
            }
          ],
          "Uniques": {
            "test.doc$uniques$unique1": {
              "Fields": [
                "f1",
                "f2"
              ]
            }
          },
          "Singleton": true
        },
        "test.obj": {
          "Kind": "Object",
          "Fields": [
            {
              "Name": "sys.QName",
              "Data": "sys.QName",
              "Required": true
            },
            {
              "Name": "sys.Container",
              "Data": "sys.string"
            },
            {
              "Name": "f1",
              "Data": "sys.string",
              "Required": true
            }
          ]
        },
        "test.rec": {
          "Kind": "CRecord",
          "Fields": [
            {
              "Name": "sys.QName",
              "Data": "sys.QName",
              "Required": true
            },
            {
              "Name": "sys.ID",
              "Data": "sys.RecordID",
              "Required": true
            },
            {
              "Name": "sys.ParentID",
              "Data": "sys.RecordID",
              "Required": true
            },
            {
              "Name": "sys.Container",
              "Data": "sys.string",
              "Required": true
            },
            {
              "Name": "sys.IsActive",
              "Data": "sys.bool"
            },
            {
              "Name": "f1",
              "Data": "sys.int64",
              "Required": true
            },
            {
              "Name": "f2",
              "Data": "sys.string"
            },
            {
              "Name": "phone",
              "DataType": {
                "Ancestor": "sys.string",
                "Constraints": {
                  "MaxLen": 25,
                  "MinLen": 1
                }
              },
              "Required": true,
              "Verifiable": true
            }
          ],
          "Uniques": {
            "test.rec$uniques$uniq1": {
              "Fields": [
                "f1"
              ]
            }
          },
          "UniqueField": "phone"
        }
      },
      "Views": {
        "test.view": {
          "Key": {
            "Partition": [
              {
                "Name": "pk_1",
                "Data": "sys.int64",
                "Required": true
              }
            ],
            "ClustCols": [
              {
                "Name": "cc_1",
                "DataType": {
                  "Ancestor": "sys.string",
                  "Constraints": {
                    "MaxLen": 100
                  }
                }
              }
            ]
          },
          "Value": [
            {
              "Name": "sys.QName",
              "Data": "sys.QName",
              "Required": true
            },
            {
              "Name": "vv_code",
              "Data": "test.string",
              "Required": true
            },
            {
              "Name": "vv_1",
              "Data": "sys.RecordID",
              "Required": true,
              "Refs": [
                "test.doc"
              ]
            }
          ]
        }
      },
      "Extensions": {
        "Commands": {
          "test.cmd": {
            "Name": "cmd",
            "Engine": "WASM",
            "Arg": "test.obj",
            "UnloggedArg": "test.obj"
          }
        },
        "Queries": {
          "test.query": {
            "Name": "query",
            "Engine": "BuiltIn",
            "Arg": "test.obj",
            "Result": "sys.ANY"
          }
        },
        "Projectors": {
          "test.projector": {
            "Name": "projector",
            "Engine": "WASM",
            "Events": {
              "test.cmd": {
                "Comment": "run projector every time when «test.cmd» command is executed",
                "Kind": [
                  "Execute"
                ]
              },
              "test.obj": {
                "Comment": "run projector every time when any command with «test.obj» argument is executed",
                "Kind": [
                  "ExecuteWithParam"
                ]
              },
              "test.rec": {
                "Comment": "run projector every time when «test.rec» is changed",
                "Kind": [
                  "Insert",
                  "Update",
                  "Activate",
                  "Deactivate"
                ]
              }
            },
            "WantErrors": true,
            "States": {
              "sys.records": [
                "test.doc",
                "test.rec"
              ]
            },
            "Intents": {
              "sys.views": [
                "test.view"
              ]
            }
          }
        }
      },
      "Roles": {
        "test.reader": {
          "Comment": "read-only role",
          "Privileges": [
            {
              "Comment": "allow reader to select some fields from test.doc and test.rec",
              "Access": "grant",
              "Kinds": [
                "Select"
              ],
              "On": [
                "test.doc",
                "test.rec"
              ],
              "Fields": [
                "f1",
                "f2"
              ]
            },
            {
              "Comment": "allow reader to select all fields from test.view",
              "Access": "grant",
              "Kinds": [
                "Select"
              ],
              "On": [
                "test.view"
              ]
            },
            {
              "Comment": "allow reader to execute test.query",
              "Access": "grant",
              "Kinds": [
                "Execute"
              ],
              "On": [
                "test.query"
              ]
            }
          ]
        },
        "test.writer": {
          "Comment": "read-write role",
          "Privileges": [
            {
              "Comment": "allow writer to do anything with test.doc, test.rec and test.view",
              "Access": "grant",
              "Kinds": [
                "Insert",
                "Update",
                "Select"
              ],
              "On": [
                "test.doc",
                "test.rec",
                "test.view"
              ]
            },
            {
              "Comment": "disable writer to update test.doc",
              "Access": "revoke",
              "Kinds": [
                "Update"
              ],
              "On": [
                "test.doc"
              ]
            },
            {
              "Comment": "allow writer to execute all test functions",
              "Access": "grant",
              "Kinds": [
                "Execute"
              ],
              "On": [
                "test.cmd",
                "test.query"
              ]
            }
          ]
        }
      }
    }
  }
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Application

type Application struct {
	Name     istructs.AppQName
	Packages map[string]*Package `json:",omitempty"`
}

type CommandFunction

type CommandFunction struct {
	Function
	UnloggedArg *appdef.QName `json:",omitempty"`
}

type CommandResource

type CommandResource struct {
	Params   *appdef.QName `json:",omitempty"`
	Unlogged *appdef.QName `json:",omitempty"`
	Result   *appdef.QName `json:",omitempty"`
}

type Container

type Container struct {
	Comment   string `json:",omitempty"`
	Name      string
	Type      appdef.QName
	MinOccurs appdef.Occurs
	MaxOccurs appdef.Occurs
}

type Data

type Data struct {
	Type
	DataKind    *appdef.DataKind `json:",omitempty"`
	Ancestor    *appdef.QName    `json:",omitempty"`
	Constraints map[string]any   `json:",omitempty"`
}

type Extension

type Extension struct {
	Type
	Name   string
	Engine string
}

type Extensions

type Extensions struct {
	Commands   map[appdef.QName]*CommandFunction `json:",omitempty"`
	Queries    map[appdef.QName]*QueryFunction   `json:",omitempty"`
	Projectors map[appdef.QName]*Projector       `json:",omitempty"`
}

type Field

type Field struct {
	Comment    string `json:",omitempty"`
	Name       appdef.FieldName
	DataType   *Data         `json:",omitempty"`
	Data       *appdef.QName `json:",omitempty"`
	Required   bool          `json:",omitempty"`
	Verifiable bool          `json:",omitempty"`
	Refs       []string      `json:",omitempty"`
}

type Function

type Function struct {
	Extension
	Arg    *appdef.QName `json:",omitempty"`
	Result *appdef.QName `json:",omitempty"`
}

type Key

type Key struct {
	Partition []*Field
	ClustCols []*Field
}

type Package

type Package struct {
	Name       string                  `json:"-"`
	Path       string                  `json:",omitempty"`
	DataTypes  map[string]*Data        `json:",omitempty"`
	Structures map[string]*Structure   `json:",omitempty"`
	Views      map[string]*View        `json:",omitempty"`
	Extensions *Extensions             `json:",omitempty"`
	Roles      map[string]*Role        `json:",omitempty"`
	Resources  map[string]*Resource    `json:",omitempty"`
	RateLimits map[string][]*RateLimit `json:",omitempty"`
}

type Privilege

type Privilege struct {
	Comment string `json:",omitempty"`
	Access  string // `grant` or `revoke`
	Kinds   []string
	On      appdef.QNames
	Fields  []string `json:",omitempty"`
}

type Projector

type Projector struct {
	Extension
	Events     map[appdef.QName]ProjectorEvent `json:",omitempty"`
	WantErrors bool                            `json:",omitempty"`
	States     map[appdef.QName]appdef.QNames  `json:",omitempty"`
	Intents    map[appdef.QName]appdef.QNames  `json:",omitempty"`
}

type ProjectorEvent

type ProjectorEvent struct {
	Comment string       `json:",omitempty"`
	On      appdef.QName `json:"-"`
	Kind    []string     `json:",omitempty"`
}

type QueryFunction

type QueryFunction struct {
	Function
}

type QueryResource

type QueryResource struct {
	Params *appdef.QName `json:",omitempty"`
	Result *appdef.QName `json:",omitempty"`
}

type RateLimit

type RateLimit struct {
	Kind                  istructs.RateLimitKind
	Period                time.Duration
	MaxAllowedPerDuration uint32
}

type Resource

type Resource struct {
	Kind    istructs.ResourceKindType
	Name    appdef.QName
	Command *CommandResource `json:",omitempty"`
	Query   *QueryResource   `json:",omitempty"`
}

type Role

type Role struct {
	Type
	Privileges []*Privilege
}

type Structure

type Structure struct {
	Type
	Kind        string
	Fields      []*Field           `json:",omitempty"`
	Containers  []*Container       `json:",omitempty"`
	Uniques     map[string]*Unique `json:",omitempty"`
	UniqueField appdef.FieldName   `json:",omitempty"`
	Singleton   bool               `json:",omitempty"`
}

type Type

type Type struct {
	Comment string          `json:",omitempty"`
	QName   appdef.QName    `json:"-"`
	Kind    appdef.TypeKind `json:"-"`
}

type Unique

type Unique struct {
	Comment string       `json:",omitempty"`
	Name    appdef.QName `json:"-"`
	Fields  []appdef.FieldName
}

type View

type View struct {
	Type
	Key   Key
	Value []*Field `json:",omitempty"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL