Restructure config on compose module
This commit is contained in:
@@ -101,8 +101,8 @@ func WalkIterator(ctx context.Context, iter dal.Iterator, mod *types.Module, f f
|
||||
|
||||
func prepFilter(filter types.RecordFilter, mod *types.Module) (dalFilter filter.Filter) {
|
||||
dalFilter = filter.ToFilter()
|
||||
if mod.ModelConfig.Partitioned {
|
||||
dalFilter = filter.ToConstraintedFilter(mod.ModelConfig.Constraints)
|
||||
if mod.Config.DAL.Partitioned {
|
||||
dalFilter = filter.ToConstraintedFilter(mod.Config.DAL.Constraints)
|
||||
}
|
||||
|
||||
return
|
||||
@@ -253,15 +253,15 @@ func recToGetters(rr ...*types.Record) (out []dal.ValueGetter) {
|
||||
}
|
||||
|
||||
func recCreateCapabilities(m *types.Module) (out capabilities.Set) {
|
||||
return capabilities.CreateCapabilities(m.ModelConfig.Capabilities...)
|
||||
return capabilities.CreateCapabilities(m.Config.DAL.Capabilities...)
|
||||
}
|
||||
|
||||
func recUpdateCapabilities(m *types.Module) (out capabilities.Set) {
|
||||
return capabilities.UpdateCapabilities(m.ModelConfig.Capabilities...)
|
||||
return capabilities.UpdateCapabilities(m.Config.DAL.Capabilities...)
|
||||
}
|
||||
|
||||
func recDeleteCapabilities(m *types.Module) (out capabilities.Set) {
|
||||
return capabilities.DeleteCapabilities(m.ModelConfig.Capabilities...)
|
||||
return capabilities.DeleteCapabilities(m.Config.DAL.Capabilities...)
|
||||
}
|
||||
|
||||
func recFilterCapabilities(f types.RecordFilter) (out capabilities.Set) {
|
||||
@@ -285,10 +285,10 @@ func recFilterCapabilities(f types.RecordFilter) (out capabilities.Set) {
|
||||
}
|
||||
|
||||
func recSearchCapabilities(m *types.Module, f types.RecordFilter) (out capabilities.Set) {
|
||||
return capabilities.SearchCapabilities(m.ModelConfig.Capabilities...).
|
||||
return capabilities.SearchCapabilities(m.Config.DAL.Capabilities...).
|
||||
Union(recFilterCapabilities(f))
|
||||
}
|
||||
|
||||
func recLookupCapabilities(m *types.Module) (out capabilities.Set) {
|
||||
return capabilities.LookupCapabilities(m.ModelConfig.Capabilities...)
|
||||
return capabilities.LookupCapabilities(m.Config.DAL.Capabilities...)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ moduleField: schema.#Resource & {
|
||||
label: {sortable: true}
|
||||
options: { goType: "types.ModuleFieldOptions" }
|
||||
encoding_strategy: { goType: "types.EncodingStrategy" }
|
||||
privacy: { goType: "types.DataPrivacyConfig" }
|
||||
privacy: { goType: "types.ModuleFieldConfigDataPrivacy" }
|
||||
private: { goType: "bool", storeIdent: "is_private" }
|
||||
required: { goType: "bool", storeIdent: "is_required" }
|
||||
visible: { goType: "bool", storeIdent: "is_visible" }
|
||||
|
||||
+1
-2
@@ -14,8 +14,7 @@ module: schema.#Resource & {
|
||||
id: schema.IdField
|
||||
handle: schema.HandleField
|
||||
meta: { goType: "rawJson" }
|
||||
model_config: { goType: "types.ModelConfig" }
|
||||
privacy: { goType: "types.DataPrivacyConfig" }
|
||||
config: { goType: "types.ModuleConfig" }
|
||||
fields: { goType: "types.ModuleFieldSet", store: false }
|
||||
namespace_id: { ident: "namespaceID", goType: "uint64", storeIdent: "rel_namespace" }
|
||||
name: {sortable: true}
|
||||
|
||||
+13
-64
@@ -548,36 +548,12 @@ endpoints:
|
||||
path: "/"
|
||||
parameters:
|
||||
post:
|
||||
- type: string
|
||||
name: name
|
||||
required: true
|
||||
title: Module Name
|
||||
- type: string
|
||||
name: handle
|
||||
required: false
|
||||
title: Module handle
|
||||
- type: types.ModelConfig
|
||||
name: modelConfig
|
||||
required: false
|
||||
title: modelConfig
|
||||
parser: types.ParseModelConfig
|
||||
- type: types.DataPrivacyConfig
|
||||
name: privacy
|
||||
required: false
|
||||
title: Data privacy config
|
||||
parser: types.ParseDataPrivacyConfig
|
||||
- type: types.ModuleFieldSet
|
||||
name: fields
|
||||
required: true
|
||||
title: Fields JSON
|
||||
- type: sqlxTypes.JSONText
|
||||
name: meta
|
||||
required: true
|
||||
title: Module meta data
|
||||
- type: map[string]string
|
||||
name: labels
|
||||
title: Module labels
|
||||
parser: label.ParseStrings
|
||||
- { type: "string", name: name, title: Name, required: true }
|
||||
- { type: "string", name: handle, title: Handle }
|
||||
- { type: "types.ModuleConfig", name: config, title: Configuration, parser: types.ParseModuleConfig }
|
||||
- { type: "sqlxTypes.JSONText", name: meta, title: Meta data, required: true }
|
||||
- { type: "types.ModuleFieldSet", name: fields, title: Fields, required: true }
|
||||
- { type: "map[string]string", name: labels, title: Labels, parser: label.ParseStrings }
|
||||
- name: read
|
||||
method: GET
|
||||
title: Read module
|
||||
@@ -599,40 +575,13 @@ endpoints:
|
||||
required: true
|
||||
title: Module ID
|
||||
post:
|
||||
- type: string
|
||||
name: name
|
||||
required: true
|
||||
title: Module Name
|
||||
- type: string
|
||||
name: handle
|
||||
required: false
|
||||
title: Module Handle
|
||||
- type: types.ModelConfig
|
||||
name: modelConfig
|
||||
required: false
|
||||
title: modelConfig
|
||||
parser: types.ParseModelConfig
|
||||
- type: types.DataPrivacyConfig
|
||||
name: privacy
|
||||
required: false
|
||||
title: Data privacy config
|
||||
parser: types.ParseDataPrivacyConfig
|
||||
- type: types.ModuleFieldSet
|
||||
name: fields
|
||||
required: true
|
||||
title: Fields JSON
|
||||
- type: sqlxTypes.JSONText
|
||||
name: meta
|
||||
required: true
|
||||
title: Module meta data
|
||||
- type: "*time.Time"
|
||||
name: updatedAt
|
||||
required: false
|
||||
title: Last update (or creation) date
|
||||
- type: map[string]string
|
||||
name: labels
|
||||
title: Module labels
|
||||
parser: label.ParseStrings
|
||||
- { type: "string", name: name, title: Name, required: true }
|
||||
- { type: "string", name: handle, title: Handle }
|
||||
- { type: "types.ModuleConfig", name: config, title: Configuration, parser: types.ParseModuleConfig }
|
||||
- { type: "sqlxTypes.JSONText", name: meta, title: Meta data, required: true }
|
||||
- { type: "types.ModuleFieldSet", name: fields, title: Fields, required: true }
|
||||
- { type: "map[string]string", name: labels, title: Labels, parser: label.ParseStrings }
|
||||
- { type: "*time.Time", name: updatedAt, title: Last update (or creation) date }
|
||||
- name: delete
|
||||
method: DELETE
|
||||
title: Delete module
|
||||
|
||||
@@ -75,7 +75,7 @@ func (ctrl *DataPrivacy) RecordList(ctx context.Context, r *request.DataPrivacyR
|
||||
|
||||
for _, s := range ss {
|
||||
// Skip the ones we don't want
|
||||
if hasReqConns && !reqConns[s.Module.ModelConfig.ConnectionID] {
|
||||
if hasReqConns && !reqConns[s.Module.Config.DAL.ConnectionID] {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -109,8 +109,7 @@ func (ctrl *Module) Create(ctx context.Context, r *request.ModuleCreate) (interf
|
||||
err error
|
||||
mod = &types.Module{
|
||||
NamespaceID: r.NamespaceID,
|
||||
ModelConfig: r.ModelConfig,
|
||||
Privacy: r.Privacy,
|
||||
Config: r.Config,
|
||||
Name: r.Name,
|
||||
Handle: r.Handle,
|
||||
Fields: r.Fields,
|
||||
@@ -129,8 +128,7 @@ func (ctrl *Module) Update(ctx context.Context, r *request.ModuleUpdate) (interf
|
||||
mod = &types.Module{
|
||||
ID: r.ModuleID,
|
||||
NamespaceID: r.NamespaceID,
|
||||
ModelConfig: r.ModelConfig,
|
||||
Privacy: r.Privacy,
|
||||
Config: r.Config,
|
||||
Name: r.Name,
|
||||
Handle: r.Handle,
|
||||
Fields: r.Fields,
|
||||
|
||||
+83
-153
@@ -88,37 +88,32 @@ type (
|
||||
|
||||
// Name POST parameter
|
||||
//
|
||||
// Module Name
|
||||
// Name
|
||||
Name string
|
||||
|
||||
// Handle POST parameter
|
||||
//
|
||||
// Module handle
|
||||
// Handle
|
||||
Handle string
|
||||
|
||||
// ModelConfig POST parameter
|
||||
// Config POST parameter
|
||||
//
|
||||
// modelConfig
|
||||
ModelConfig types.ModelConfig
|
||||
|
||||
// Privacy POST parameter
|
||||
//
|
||||
// Data privacy config
|
||||
Privacy types.DataPrivacyConfig
|
||||
|
||||
// Fields POST parameter
|
||||
//
|
||||
// Fields JSON
|
||||
Fields types.ModuleFieldSet
|
||||
// Configuration
|
||||
Config types.ModuleConfig
|
||||
|
||||
// Meta POST parameter
|
||||
//
|
||||
// Module meta data
|
||||
// Meta data
|
||||
Meta sqlxTypes.JSONText
|
||||
|
||||
// Fields POST parameter
|
||||
//
|
||||
// Fields
|
||||
Fields types.ModuleFieldSet
|
||||
|
||||
// Labels POST parameter
|
||||
//
|
||||
// Module labels
|
||||
// Labels
|
||||
Labels map[string]string
|
||||
}
|
||||
|
||||
@@ -147,43 +142,38 @@ type (
|
||||
|
||||
// Name POST parameter
|
||||
//
|
||||
// Module Name
|
||||
// Name
|
||||
Name string
|
||||
|
||||
// Handle POST parameter
|
||||
//
|
||||
// Module Handle
|
||||
// Handle
|
||||
Handle string
|
||||
|
||||
// ModelConfig POST parameter
|
||||
// Config POST parameter
|
||||
//
|
||||
// modelConfig
|
||||
ModelConfig types.ModelConfig
|
||||
|
||||
// Privacy POST parameter
|
||||
//
|
||||
// Data privacy config
|
||||
Privacy types.DataPrivacyConfig
|
||||
|
||||
// Fields POST parameter
|
||||
//
|
||||
// Fields JSON
|
||||
Fields types.ModuleFieldSet
|
||||
// Configuration
|
||||
Config types.ModuleConfig
|
||||
|
||||
// Meta POST parameter
|
||||
//
|
||||
// Module meta data
|
||||
// Meta data
|
||||
Meta sqlxTypes.JSONText
|
||||
|
||||
// Fields POST parameter
|
||||
//
|
||||
// Fields
|
||||
Fields types.ModuleFieldSet
|
||||
|
||||
// Labels POST parameter
|
||||
//
|
||||
// Labels
|
||||
Labels map[string]string
|
||||
|
||||
// UpdatedAt POST parameter
|
||||
//
|
||||
// Last update (or creation) date
|
||||
UpdatedAt *time.Time
|
||||
|
||||
// Labels POST parameter
|
||||
//
|
||||
// Module labels
|
||||
Labels map[string]string
|
||||
}
|
||||
|
||||
ModuleDelete struct {
|
||||
@@ -391,10 +381,9 @@ func (r ModuleCreate) Auditable() map[string]interface{} {
|
||||
"namespaceID": r.NamespaceID,
|
||||
"name": r.Name,
|
||||
"handle": r.Handle,
|
||||
"modelConfig": r.ModelConfig,
|
||||
"privacy": r.Privacy,
|
||||
"fields": r.Fields,
|
||||
"config": r.Config,
|
||||
"meta": r.Meta,
|
||||
"fields": r.Fields,
|
||||
"labels": r.Labels,
|
||||
}
|
||||
}
|
||||
@@ -415,18 +404,8 @@ func (r ModuleCreate) GetHandle() string {
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleCreate) GetModelConfig() types.ModelConfig {
|
||||
return r.ModelConfig
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleCreate) GetPrivacy() types.DataPrivacyConfig {
|
||||
return r.Privacy
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleCreate) GetFields() types.ModuleFieldSet {
|
||||
return r.Fields
|
||||
func (r ModuleCreate) GetConfig() types.ModuleConfig {
|
||||
return r.Config
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
@@ -434,6 +413,11 @@ func (r ModuleCreate) GetMeta() sqlxTypes.JSONText {
|
||||
return r.Meta
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleCreate) GetFields() types.ModuleFieldSet {
|
||||
return r.Fields
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleCreate) GetLabels() map[string]string {
|
||||
return r.Labels
|
||||
@@ -474,25 +458,13 @@ func (r *ModuleCreate) Fill(req *http.Request) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.MultipartForm.Value["modelConfig[]"]; ok {
|
||||
r.ModelConfig, err = types.ParseModelConfig(val)
|
||||
if val, ok := req.MultipartForm.Value["config[]"]; ok {
|
||||
r.Config, err = types.ParseModuleConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if val, ok := req.MultipartForm.Value["modelConfig"]; ok {
|
||||
r.ModelConfig, err = types.ParseModelConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.MultipartForm.Value["privacy[]"]; ok {
|
||||
r.Privacy, err = types.ParseDataPrivacyConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if val, ok := req.MultipartForm.Value["privacy"]; ok {
|
||||
r.Privacy, err = types.ParseDataPrivacyConfig(val)
|
||||
} else if val, ok := req.MultipartForm.Value["config"]; ok {
|
||||
r.Config, err = types.ParseModuleConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -540,25 +512,20 @@ func (r *ModuleCreate) Fill(req *http.Request) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.Form["modelConfig[]"]; ok {
|
||||
r.ModelConfig, err = types.ParseModelConfig(val)
|
||||
if val, ok := req.Form["config[]"]; ok {
|
||||
r.Config, err = types.ParseModuleConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if val, ok := req.Form["modelConfig"]; ok {
|
||||
r.ModelConfig, err = types.ParseModelConfig(val)
|
||||
} else if val, ok := req.Form["config"]; ok {
|
||||
r.Config, err = types.ParseModuleConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.Form["privacy[]"]; ok {
|
||||
r.Privacy, err = types.ParseDataPrivacyConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if val, ok := req.Form["privacy"]; ok {
|
||||
r.Privacy, err = types.ParseDataPrivacyConfig(val)
|
||||
if val, ok := req.Form["meta"]; ok && len(val) > 0 {
|
||||
r.Meta, err = payload.ParseJSONTextWithErr(val[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -571,13 +538,6 @@ func (r *ModuleCreate) Fill(req *http.Request) (err error) {
|
||||
// }
|
||||
//}
|
||||
|
||||
if val, ok := req.Form["meta"]; ok && len(val) > 0 {
|
||||
r.Meta, err = payload.ParseJSONTextWithErr(val[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.Form["labels[]"]; ok {
|
||||
r.Labels, err = label.ParseStrings(val)
|
||||
if err != nil {
|
||||
@@ -665,12 +625,11 @@ func (r ModuleUpdate) Auditable() map[string]interface{} {
|
||||
"moduleID": r.ModuleID,
|
||||
"name": r.Name,
|
||||
"handle": r.Handle,
|
||||
"modelConfig": r.ModelConfig,
|
||||
"privacy": r.Privacy,
|
||||
"fields": r.Fields,
|
||||
"config": r.Config,
|
||||
"meta": r.Meta,
|
||||
"updatedAt": r.UpdatedAt,
|
||||
"fields": r.Fields,
|
||||
"labels": r.Labels,
|
||||
"updatedAt": r.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,18 +654,8 @@ func (r ModuleUpdate) GetHandle() string {
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdate) GetModelConfig() types.ModelConfig {
|
||||
return r.ModelConfig
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdate) GetPrivacy() types.DataPrivacyConfig {
|
||||
return r.Privacy
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdate) GetFields() types.ModuleFieldSet {
|
||||
return r.Fields
|
||||
func (r ModuleUpdate) GetConfig() types.ModuleConfig {
|
||||
return r.Config
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
@@ -715,8 +664,8 @@ func (r ModuleUpdate) GetMeta() sqlxTypes.JSONText {
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdate) GetUpdatedAt() *time.Time {
|
||||
return r.UpdatedAt
|
||||
func (r ModuleUpdate) GetFields() types.ModuleFieldSet {
|
||||
return r.Fields
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
@@ -724,6 +673,11 @@ func (r ModuleUpdate) GetLabels() map[string]string {
|
||||
return r.Labels
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ModuleUpdate) GetUpdatedAt() *time.Time {
|
||||
return r.UpdatedAt
|
||||
}
|
||||
|
||||
// Fill processes request and fills internal variables
|
||||
func (r *ModuleUpdate) Fill(req *http.Request) (err error) {
|
||||
|
||||
@@ -759,25 +713,13 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.MultipartForm.Value["modelConfig[]"]; ok {
|
||||
r.ModelConfig, err = types.ParseModelConfig(val)
|
||||
if val, ok := req.MultipartForm.Value["config[]"]; ok {
|
||||
r.Config, err = types.ParseModuleConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if val, ok := req.MultipartForm.Value["modelConfig"]; ok {
|
||||
r.ModelConfig, err = types.ParseModelConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.MultipartForm.Value["privacy[]"]; ok {
|
||||
r.Privacy, err = types.ParseDataPrivacyConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if val, ok := req.MultipartForm.Value["privacy"]; ok {
|
||||
r.Privacy, err = types.ParseDataPrivacyConfig(val)
|
||||
} else if val, ok := req.MultipartForm.Value["config"]; ok {
|
||||
r.Config, err = types.ParseModuleConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -790,13 +732,6 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.MultipartForm.Value["updatedAt"]; ok && len(val) > 0 {
|
||||
r.UpdatedAt, err = payload.ParseISODatePtrWithErr(val[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.MultipartForm.Value["labels[]"]; ok {
|
||||
r.Labels, err = label.ParseStrings(val)
|
||||
if err != nil {
|
||||
@@ -808,6 +743,13 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.MultipartForm.Value["updatedAt"]; ok && len(val) > 0 {
|
||||
r.UpdatedAt, err = payload.ParseISODatePtrWithErr(val[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,25 +774,20 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.Form["modelConfig[]"]; ok {
|
||||
r.ModelConfig, err = types.ParseModelConfig(val)
|
||||
if val, ok := req.Form["config[]"]; ok {
|
||||
r.Config, err = types.ParseModuleConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if val, ok := req.Form["modelConfig"]; ok {
|
||||
r.ModelConfig, err = types.ParseModelConfig(val)
|
||||
} else if val, ok := req.Form["config"]; ok {
|
||||
r.Config, err = types.ParseModuleConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.Form["privacy[]"]; ok {
|
||||
r.Privacy, err = types.ParseDataPrivacyConfig(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if val, ok := req.Form["privacy"]; ok {
|
||||
r.Privacy, err = types.ParseDataPrivacyConfig(val)
|
||||
if val, ok := req.Form["meta"]; ok && len(val) > 0 {
|
||||
r.Meta, err = payload.ParseJSONTextWithErr(val[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -863,20 +800,6 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) {
|
||||
// }
|
||||
//}
|
||||
|
||||
if val, ok := req.Form["meta"]; ok && len(val) > 0 {
|
||||
r.Meta, err = payload.ParseJSONTextWithErr(val[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.Form["updatedAt"]; ok && len(val) > 0 {
|
||||
r.UpdatedAt, err = payload.ParseISODatePtrWithErr(val[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.Form["labels[]"]; ok {
|
||||
r.Labels, err = label.ParseStrings(val)
|
||||
if err != nil {
|
||||
@@ -888,6 +811,13 @@ func (r *ModuleUpdate) Fill(req *http.Request) (err error) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := req.Form["updatedAt"]; ok && len(val) > 0 {
|
||||
r.UpdatedAt, err = payload.ParseISODatePtrWithErr(val[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
+35
-23
@@ -295,15 +295,15 @@ func (svc module) procDal(m *types.Module) {
|
||||
return
|
||||
}
|
||||
|
||||
ii := svc.dal.SearchModelIssues(m.ModelConfig.ConnectionID, m.ID)
|
||||
ii := svc.dal.SearchModelIssues(m.Config.DAL.ConnectionID, m.ID)
|
||||
if len(ii) == 0 {
|
||||
m.ModelConfig.Issues = nil
|
||||
m.Config.DAL.Issues = nil
|
||||
return
|
||||
}
|
||||
|
||||
m.ModelConfig.Issues = make([]string, len(ii))
|
||||
m.Config.DAL.Issues = make([]string, len(ii))
|
||||
for i, err := range ii {
|
||||
m.ModelConfig.Issues[i] = err.Error()
|
||||
m.Config.DAL.Issues[i] = err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +453,7 @@ func (svc module) FindSensitive(ctx context.Context, filter types.PrivacyModuleF
|
||||
}
|
||||
|
||||
for _, m := range mm {
|
||||
cMeta, err := svc.dal.GetConnectionMeta(ctx, m.ModelConfig.ConnectionID)
|
||||
cMeta, err := svc.dal.GetConnectionMeta(ctx, m.Config.DAL.ConnectionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -534,7 +534,24 @@ func (svc module) updater(ctx context.Context, namespaceID, moduleID uint64, act
|
||||
}
|
||||
|
||||
if changes&moduleChanged > 0 {
|
||||
if old.ModelConfig.ConnectionID != m.ModelConfig.ConnectionID {
|
||||
{
|
||||
// properly resolve connection ID 0 to the actual ID of the default connection
|
||||
var defConn dal.ConnectionMeta
|
||||
defConn, err = svc.dal.GetConnectionMeta(ctx, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
if old.Config.DAL.ConnectionID == 0 {
|
||||
old.Config.DAL.ConnectionID = defConn.ConnectionID
|
||||
}
|
||||
if m.Config.DAL.ConnectionID == 0 {
|
||||
m.Config.DAL.ConnectionID = defConn.ConnectionID
|
||||
}
|
||||
}
|
||||
|
||||
if old.Config.DAL.ConnectionID != m.Config.DAL.ConnectionID {
|
||||
return fmt.Errorf("unable to switch connection for existing models: run data migration")
|
||||
}
|
||||
|
||||
@@ -551,7 +568,7 @@ func (svc module) updater(ctx context.Context, namespaceID, moduleID uint64, act
|
||||
|
||||
// @todo rethink how model issues and attempted module update with records should interact.
|
||||
// this is a temporary solution but should be re-thinked.
|
||||
modelIssues := svc.dal.SearchModelIssues(m.ModelConfig.ConnectionID, m.ID)
|
||||
modelIssues := svc.dal.SearchModelIssues(m.Config.DAL.ConnectionID, m.ID)
|
||||
if len(modelIssues) == 0 {
|
||||
if set, _, err = dalutils.ComposeRecordsList(ctx, svc.dal, m, types.RecordFilter{Paging: filter.Paging{Limit: 1}, Check: func(r *types.Record) (bool, error) { return true, nil }}); err != nil {
|
||||
return err
|
||||
@@ -718,14 +735,9 @@ func (svc module) handleUpdate(ctx context.Context, upd *types.Module) moduleUpd
|
||||
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(res.ModelConfig, upd.ModelConfig) {
|
||||
if !reflect.DeepEqual(res.Config, upd.Config) {
|
||||
changes |= moduleChanged
|
||||
res.ModelConfig = upd.ModelConfig
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(res.Privacy, upd.Privacy) {
|
||||
changes |= moduleChanged
|
||||
res.Privacy = upd.Privacy
|
||||
res.Config = upd.Config
|
||||
}
|
||||
|
||||
// @todo make field-change detection more optimal
|
||||
@@ -1148,7 +1160,7 @@ func dalAttributeReplace(ctx context.Context, dmm dalModelManager, ns *types.Nam
|
||||
// Removes a connection from DAL service
|
||||
func DalModelRemove(ctx context.Context, dmm dalModelManager, mm ...*types.Module) (err error) {
|
||||
for _, m := range mm {
|
||||
if err = dmm.RemoveModel(ctx, m.ModelConfig.ConnectionID, m.ID); err != nil {
|
||||
if err = dmm.RemoveModel(ctx, m.Config.DAL.ConnectionID, m.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1188,14 +1200,14 @@ func moduleToModel(ctx context.Context, dmm dalModelManager, ns *types.Namespace
|
||||
Resource: mod.RbacResource(),
|
||||
ResourceID: mod.ID,
|
||||
ResourceType: types.ModuleResourceType,
|
||||
SensitivityLevel: mod.Privacy.SensitivityLevel,
|
||||
Capabilities: mod.ModelConfig.Capabilities,
|
||||
SensitivityLevel: mod.Config.Privacy.SensitivityLevel,
|
||||
Capabilities: mod.Config.DAL.Capabilities,
|
||||
}
|
||||
|
||||
// - make the model ident
|
||||
ident := cm.DefaultModelIdent
|
||||
if mod.ModelConfig.Partitioned {
|
||||
tpl := mod.ModelConfig.PartitionFormat
|
||||
if mod.Config.DAL.Partitioned {
|
||||
tpl := mod.Config.DAL.PartitionFormat
|
||||
if tpl == "" {
|
||||
tpl = cm.DefaultPartitionFormat
|
||||
}
|
||||
@@ -1249,7 +1261,7 @@ func moduleFieldsToAttributes(ctx context.Context, cm dal.ConnectionMeta, ns *ty
|
||||
|
||||
// moduleSystemFieldsToAttributes converts all system-defined module fields to attributes
|
||||
func moduleSystemFieldsToAttributes(ctx context.Context, cm dal.ConnectionMeta, ns *types.Namespace, mod *types.Module) (out dal.AttributeSet, err error) {
|
||||
if mod.ModelConfig.Partitioned {
|
||||
if mod.Config.DAL.Partitioned {
|
||||
return partitionedModuleSystemFieldsToAttributes(cm, mod), nil
|
||||
}
|
||||
return defaultModuleSystemFieldsToAttributes(), nil
|
||||
@@ -1258,7 +1270,7 @@ func moduleSystemFieldsToAttributes(ctx context.Context, cm dal.ConnectionMeta,
|
||||
// partitionedModuleSystemFieldsToAttributes converts all system-defined module fields to attributes
|
||||
// keeping user-defined codec in mind
|
||||
func partitionedModuleSystemFieldsToAttributes(cm dal.ConnectionMeta, mod *types.Module) (out dal.AttributeSet) {
|
||||
sysEnc := mod.ModelConfig.SystemFieldEncoding
|
||||
sysEnc := mod.Config.DAL.SystemFieldEncoding
|
||||
|
||||
if sysEnc.ID != nil {
|
||||
out = append(out, dal.PrimaryAttribute(sysID, modelFieldCodec(cm, mod, &types.ModuleField{Name: sysID, EncodingStrategy: *sysEnc.ID})))
|
||||
@@ -1410,7 +1422,7 @@ func moduleFieldToAttribute(ctx context.Context, cm dal.ConnectionMeta, mod *typ
|
||||
func modulesByConnection(modules ...*types.Module) map[uint64]types.ModuleSet {
|
||||
out := make(map[uint64]types.ModuleSet)
|
||||
for _, mod := range modules {
|
||||
out[mod.ModelConfig.ConnectionID] = append(out[mod.ModelConfig.ConnectionID], mod)
|
||||
out[mod.Config.DAL.ConnectionID] = append(out[mod.Config.DAL.ConnectionID], mod)
|
||||
}
|
||||
|
||||
return out
|
||||
@@ -1452,7 +1464,7 @@ func modelFieldCodec(cm dal.ConnectionMeta, mod *types.Module, f *types.ModuleFi
|
||||
|
||||
// baseModelFieldCodec returns the DAL codec the given module field should use by default
|
||||
func baseModelFieldCodec(cm dal.ConnectionMeta, mod *types.Module, f *types.ModuleField) dal.Codec {
|
||||
if mod.ModelConfig.Partitioned {
|
||||
if mod.Config.DAL.Partitioned {
|
||||
return &dal.CodecPlain{}
|
||||
}
|
||||
|
||||
|
||||
+53
-95
@@ -3,44 +3,31 @@ package types
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
discovery "github.com/cortezaproject/corteza-server/discovery/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/sql"
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
"time"
|
||||
|
||||
discovery "github.com/cortezaproject/corteza-server/discovery/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/dal"
|
||||
"github.com/cortezaproject/corteza-server/pkg/dal/capabilities"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/locale"
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type (
|
||||
ModelConfig struct {
|
||||
ConnectionID uint64 `json:"connectionID,string"`
|
||||
Capabilities capabilities.Set `json:"capabilities"`
|
||||
|
||||
Issues []string `json:"issues,omitempty"`
|
||||
|
||||
Constraints map[string][]any `json:"constraints"`
|
||||
|
||||
Partitioned bool `json:"partitioned"`
|
||||
PartitionFormat string `json:"partitionFormat"`
|
||||
|
||||
SystemFieldEncoding SystemFieldEncoding `json:"systemFieldEncoding"`
|
||||
}
|
||||
|
||||
DataPrivacyConfig struct {
|
||||
SensitivityLevel uint64 `json:"sensitivityLevel,string,omitempty"`
|
||||
UsageDisclosure string `json:"usageDisclosure"`
|
||||
}
|
||||
|
||||
Module struct {
|
||||
ID uint64 `json:"moduleID,string"`
|
||||
Handle string `json:"handle"`
|
||||
Meta types.JSONText `json:"meta"`
|
||||
ID uint64 `json:"moduleID,string"`
|
||||
Handle string `json:"handle"`
|
||||
|
||||
ModelConfig ModelConfig `json:"modelConfig"`
|
||||
Privacy DataPrivacyConfig `json:"privacy"`
|
||||
// collection of configurations for various subsystems that
|
||||
// use this module and how it affects their behaviour
|
||||
Config ModuleConfig `json:"config"`
|
||||
|
||||
// @todo should be removed and placed into a separate subsystem
|
||||
// mostly because we want to allow client apps to store
|
||||
// application configs away from the module config
|
||||
// using separate access-control
|
||||
Meta types.JSONText `json:"meta"`
|
||||
|
||||
Fields ModuleFieldSet `json:"fields"`
|
||||
|
||||
@@ -76,10 +63,41 @@ type (
|
||||
DeletedBy *EncodingStrategy `json:"deletedBy"`
|
||||
}
|
||||
|
||||
ModuleMeta struct {
|
||||
ModuleConfig struct {
|
||||
// How and where the records of this module are stored in the database
|
||||
DAL ModuleConfigDAL `json:"dal"`
|
||||
|
||||
// Record data privacy settings
|
||||
Privacy ModuleConfigDataPrivacy `json:"privacy"`
|
||||
|
||||
// @todo we need to transfer this from meta!!
|
||||
Discovery discovery.ModuleMeta `json:"discovery"`
|
||||
}
|
||||
|
||||
ModuleConfigDAL struct {
|
||||
ConnectionID uint64 `json:"connectionID,string"`
|
||||
Capabilities capabilities.Set `json:"capabilities"`
|
||||
|
||||
Issues []string `json:"issues,omitempty"`
|
||||
|
||||
Constraints map[string][]any `json:"constraints"`
|
||||
|
||||
Partitioned bool `json:"partitioned"`
|
||||
PartitionFormat string `json:"partitionFormat"`
|
||||
|
||||
SystemFieldEncoding SystemFieldEncoding `json:"systemFieldEncoding"`
|
||||
}
|
||||
|
||||
ModuleConfigDataPrivacy struct {
|
||||
// Define the highest sensitivity level which
|
||||
// can be configured on the module fields
|
||||
SensitivityLevel uint64 `json:"sensitivityLevel,string,omitempty"`
|
||||
|
||||
UsageDisclosure string `json:"usageDisclosure"`
|
||||
}
|
||||
|
||||
ModelMeta map[string]any
|
||||
|
||||
ModuleFilter struct {
|
||||
ModuleID []uint64 `json:"moduleID"`
|
||||
NamespaceID uint64 `json:"namespaceID,string"`
|
||||
@@ -111,7 +129,7 @@ func (m Module) Clone() *Module {
|
||||
}
|
||||
|
||||
func (m Module) HasIssues() bool {
|
||||
return len(m.ModelConfig.Issues) > 0
|
||||
return len(m.Config.DAL.Issues) > 0
|
||||
}
|
||||
|
||||
// We won't worry about fields at this point
|
||||
@@ -126,7 +144,7 @@ func (m *Module) encodeTranslations() (out locale.ResourceTranslationSet) {
|
||||
|
||||
func (m *Module) ModelRef() dal.ModelRef {
|
||||
return dal.ModelRef{
|
||||
ConnectionID: m.ModelConfig.ConnectionID,
|
||||
ConnectionID: m.Config.DAL.ConnectionID,
|
||||
|
||||
ResourceID: m.ID,
|
||||
|
||||
@@ -147,45 +165,13 @@ func (set ModuleSet) FindByHandle(handle string) *Module {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nm *ModuleMeta) Scan(value interface{}) error {
|
||||
//lint:ignore S1034 This typecast is intentional, we need to get []byte out of a []uint8
|
||||
switch value.(type) {
|
||||
case nil:
|
||||
*nm = ModuleMeta{}
|
||||
case []uint8:
|
||||
b := value.([]byte)
|
||||
if err := json.Unmarshal(b, nm); err != nil {
|
||||
return errors.Wrapf(err, "cannot scan '%v' into ModuleMeta", string(b))
|
||||
}
|
||||
}
|
||||
func (c *ModuleConfig) Scan(src any) error { return sql.ParseJSON(src, c) }
|
||||
func (c ModuleConfig) Value() (driver.Value, error) { return json.Marshal(c) }
|
||||
|
||||
return nil
|
||||
}
|
||||
func (m *ModelMeta) Scan(src any) error { return sql.ParseJSON(src, m) }
|
||||
func (m ModelMeta) Value() (driver.Value, error) { return json.Marshal(m) }
|
||||
|
||||
func (nm ModuleMeta) Value() (driver.Value, error) {
|
||||
return json.Marshal(nm)
|
||||
}
|
||||
|
||||
func (nm *ModelConfig) Scan(value interface{}) error {
|
||||
//lint:ignore S1034 This typecast is intentional, we need to get []byte out of a []uint8
|
||||
switch value.(type) {
|
||||
case nil:
|
||||
*nm = ModelConfig{}
|
||||
case []uint8:
|
||||
b := value.([]byte)
|
||||
if err := json.Unmarshal(b, nm); err != nil {
|
||||
return errors.Wrapf(err, "cannot scan '%v' into ModelConfig", string(b))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nm ModelConfig) Value() (driver.Value, error) {
|
||||
return json.Marshal(nm)
|
||||
}
|
||||
|
||||
func ParseModelConfig(ss []string) (m ModelConfig, err error) {
|
||||
func ParseModuleConfig(ss []string) (m ModuleConfig, err error) {
|
||||
if len(ss) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -193,31 +179,3 @@ func ParseModelConfig(ss []string) (m ModelConfig, err error) {
|
||||
err = json.Unmarshal([]byte(ss[0]), &m)
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *DataPrivacyConfig) Scan(value interface{}) error {
|
||||
//lint:ignore S1034 This typecast is intentional, we need to get []byte out of a []uint8
|
||||
switch value.(type) {
|
||||
case nil:
|
||||
*nm = DataPrivacyConfig{}
|
||||
case []uint8:
|
||||
b := value.([]byte)
|
||||
if err := json.Unmarshal(b, nm); err != nil {
|
||||
return errors.Wrapf(err, "cannot scan '%v' into DataPrivacyConfig", string(b))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nm DataPrivacyConfig) Value() (driver.Value, error) {
|
||||
return json.Marshal(nm)
|
||||
}
|
||||
|
||||
func ParseDataPrivacyConfig(ss []string) (dpc DataPrivacyConfig, err error) {
|
||||
if len(ss) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(ss[0]), &dpc)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package types
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"github.com/cortezaproject/corteza-server/pkg/sql"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -28,7 +29,7 @@ type (
|
||||
|
||||
EncodingStrategy EncodingStrategy `json:"encodingStrategy"`
|
||||
|
||||
Privacy DataPrivacyConfig `json:"privacy"`
|
||||
Privacy ModuleFieldConfigDataPrivacy `json:"privacy"`
|
||||
|
||||
Private bool `json:"isPrivate"`
|
||||
Required bool `json:"isRequired"`
|
||||
@@ -50,6 +51,14 @@ type (
|
||||
Label string `json:"label"`
|
||||
}
|
||||
|
||||
ModuleFieldConfigDataPrivacy struct {
|
||||
// Define the highest sensitivity level which
|
||||
// can be configured on the module fields
|
||||
SensitivityLevel uint64 `json:"sensitivityLevel,string,omitempty"`
|
||||
|
||||
UsageDisclosure string `json:"usageDisclosure"`
|
||||
}
|
||||
|
||||
EncodingStrategy struct {
|
||||
*EncodingStrategyAlias `json:"alias,omitempty"`
|
||||
*EncodingStrategyJSON `json:"json,omitempty"`
|
||||
@@ -520,3 +529,6 @@ func (f ModuleField) IsRef() bool {
|
||||
func (f ModuleField) IsSensitive() bool {
|
||||
return f.Privacy.SensitivityLevel > 0
|
||||
}
|
||||
|
||||
func (p *ModuleFieldConfigDataPrivacy) Scan(src any) error { return sql.ParseJSON(src, p) }
|
||||
func (p ModuleFieldConfigDataPrivacy) Value() (driver.Value, error) { return json.Marshal(p) }
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package sql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func ParseJSON(raw any, dest any) (error) {
|
||||
var (
|
||||
data []byte
|
||||
)
|
||||
|
||||
if b, ok := raw.([]byte); ok {
|
||||
data = b
|
||||
} else if s, ok := raw.(string); ok {
|
||||
data = []byte(s)
|
||||
} else if raw == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, dest); err != nil {
|
||||
return fmt.Errorf("can not scan JSON into %T: %w", dest, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Generated
+30
-34
@@ -244,38 +244,37 @@ type (
|
||||
|
||||
// auxComposeModule is an auxiliary structure used for transporting to/from RDBMS store
|
||||
auxComposeModule struct {
|
||||
ID uint64 `db:"id"`
|
||||
Handle string `db:"handle"`
|
||||
Meta rawJson `db:"meta"`
|
||||
ModelConfig composeType.ModelConfig `db:"model_config"`
|
||||
Privacy composeType.DataPrivacyConfig `db:"privacy"`
|
||||
NamespaceID uint64 `db:"namespace_id"`
|
||||
Name string `db:"name"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt *time.Time `db:"updated_at"`
|
||||
DeletedAt *time.Time `db:"deleted_at"`
|
||||
ID uint64 `db:"id"`
|
||||
Handle string `db:"handle"`
|
||||
Meta rawJson `db:"meta"`
|
||||
Config composeType.ModuleConfig `db:"config"`
|
||||
NamespaceID uint64 `db:"namespace_id"`
|
||||
Name string `db:"name"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt *time.Time `db:"updated_at"`
|
||||
DeletedAt *time.Time `db:"deleted_at"`
|
||||
}
|
||||
|
||||
// auxComposeModuleField is an auxiliary structure used for transporting to/from RDBMS store
|
||||
auxComposeModuleField struct {
|
||||
ID uint64 `db:"id"`
|
||||
ModuleID uint64 `db:"module_id"`
|
||||
Place int `db:"place"`
|
||||
Kind string `db:"kind"`
|
||||
Name string `db:"name"`
|
||||
Label string `db:"label"`
|
||||
Options composeType.ModuleFieldOptions `db:"options"`
|
||||
EncodingStrategy composeType.EncodingStrategy `db:"encoding_strategy"`
|
||||
Privacy composeType.DataPrivacyConfig `db:"privacy"`
|
||||
Private bool `db:"private"`
|
||||
Required bool `db:"required"`
|
||||
Visible bool `db:"visible"`
|
||||
Multi bool `db:"multi"`
|
||||
DefaultValue composeType.RecordValueSet `db:"default_value"`
|
||||
Expressions composeType.ModuleFieldExpr `db:"expressions"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt *time.Time `db:"updated_at"`
|
||||
DeletedAt *time.Time `db:"deleted_at"`
|
||||
ID uint64 `db:"id"`
|
||||
ModuleID uint64 `db:"module_id"`
|
||||
Place int `db:"place"`
|
||||
Kind string `db:"kind"`
|
||||
Name string `db:"name"`
|
||||
Label string `db:"label"`
|
||||
Options composeType.ModuleFieldOptions `db:"options"`
|
||||
EncodingStrategy composeType.EncodingStrategy `db:"encoding_strategy"`
|
||||
Privacy composeType.ModuleFieldConfigDataPrivacy `db:"privacy"`
|
||||
Private bool `db:"private"`
|
||||
Required bool `db:"required"`
|
||||
Visible bool `db:"visible"`
|
||||
Multi bool `db:"multi"`
|
||||
DefaultValue composeType.RecordValueSet `db:"default_value"`
|
||||
Expressions composeType.ModuleFieldExpr `db:"expressions"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt *time.Time `db:"updated_at"`
|
||||
DeletedAt *time.Time `db:"deleted_at"`
|
||||
}
|
||||
|
||||
// auxComposeNamespace is an auxiliary structure used for transporting to/from RDBMS store
|
||||
@@ -1442,8 +1441,7 @@ func (aux *auxComposeModule) encode(res *composeType.Module) (_ error) {
|
||||
aux.ID = res.ID
|
||||
aux.Handle = res.Handle
|
||||
aux.Meta = res.Meta
|
||||
aux.ModelConfig = res.ModelConfig
|
||||
aux.Privacy = res.Privacy
|
||||
aux.Config = res.Config
|
||||
aux.NamespaceID = res.NamespaceID
|
||||
aux.Name = res.Name
|
||||
aux.CreatedAt = res.CreatedAt
|
||||
@@ -1460,8 +1458,7 @@ func (aux auxComposeModule) decode() (res *composeType.Module, _ error) {
|
||||
res.ID = aux.ID
|
||||
res.Handle = aux.Handle
|
||||
res.Meta = aux.Meta
|
||||
res.ModelConfig = aux.ModelConfig
|
||||
res.Privacy = aux.Privacy
|
||||
res.Config = aux.Config
|
||||
res.NamespaceID = aux.NamespaceID
|
||||
res.Name = aux.Name
|
||||
res.CreatedAt = aux.CreatedAt
|
||||
@@ -1478,8 +1475,7 @@ func (aux *auxComposeModule) scan(row scanner) error {
|
||||
&aux.ID,
|
||||
&aux.Handle,
|
||||
&aux.Meta,
|
||||
&aux.ModelConfig,
|
||||
&aux.Privacy,
|
||||
&aux.Config,
|
||||
&aux.NamespaceID,
|
||||
&aux.Name,
|
||||
&aux.CreatedAt,
|
||||
|
||||
Generated
+4
-8
@@ -1636,8 +1636,7 @@ var (
|
||||
"id",
|
||||
"handle",
|
||||
"meta",
|
||||
"model_config",
|
||||
"privacy",
|
||||
"config",
|
||||
"rel_namespace",
|
||||
"name",
|
||||
"created_at",
|
||||
@@ -1655,8 +1654,7 @@ var (
|
||||
"id": res.ID,
|
||||
"handle": res.Handle,
|
||||
"meta": res.Meta,
|
||||
"model_config": res.ModelConfig,
|
||||
"privacy": res.Privacy,
|
||||
"config": res.Config,
|
||||
"rel_namespace": res.NamespaceID,
|
||||
"name": res.Name,
|
||||
"created_at": res.CreatedAt,
|
||||
@@ -1677,8 +1675,7 @@ var (
|
||||
goqu.Record{
|
||||
"handle": res.Handle,
|
||||
"meta": res.Meta,
|
||||
"model_config": res.ModelConfig,
|
||||
"privacy": res.Privacy,
|
||||
"config": res.Config,
|
||||
"rel_namespace": res.NamespaceID,
|
||||
"name": res.Name,
|
||||
"created_at": res.CreatedAt,
|
||||
@@ -1697,8 +1694,7 @@ var (
|
||||
Set(goqu.Record{
|
||||
"handle": res.Handle,
|
||||
"meta": res.Meta,
|
||||
"model_config": res.ModelConfig,
|
||||
"privacy": res.Privacy,
|
||||
"config": res.Config,
|
||||
"rel_namespace": res.NamespaceID,
|
||||
"name": res.Name,
|
||||
"created_at": res.CreatedAt,
|
||||
|
||||
@@ -6,12 +6,11 @@ import (
|
||||
)
|
||||
|
||||
func fix202209_extendComposeModuleForPrivacyAndDAL(ctx context.Context, s *Store) (err error) {
|
||||
s.log(ctx).Info("extending compose_module table with privacy and model_config columns")
|
||||
s.log(ctx).Info("extending compose_module table with config column")
|
||||
return s.SchemaAPI.AddColumn(
|
||||
ctx, s.DB,
|
||||
&Table{Name: "compose_module"},
|
||||
&Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "privacy"},
|
||||
&Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "model_config"},
|
||||
&Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "config"},
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -448,8 +448,7 @@ func tableComposeModule() *Table {
|
||||
ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
|
||||
ColumnDef("name", ColumnTypeText),
|
||||
ColumnDef("meta", ColumnTypeJson),
|
||||
ColumnDef("privacy", ColumnTypeJson),
|
||||
ColumnDef("model_config", ColumnTypeJson),
|
||||
ColumnDef("config", ColumnTypeJson),
|
||||
CUDTimestamps,
|
||||
|
||||
AddIndex("namespace", IColumn("rel_namespace")),
|
||||
|
||||
@@ -22,9 +22,11 @@ func Test_dal_crud_compose_record_create(t *testing.T) {
|
||||
helpers.AllowMeRecordCRUD(h)
|
||||
|
||||
ns := h.createNamespace("test")
|
||||
module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModelConfig{
|
||||
ConnectionID: 0,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModuleConfig{
|
||||
DAL: types.ModuleConfigDAL{
|
||||
ConnectionID: 0,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
},
|
||||
})
|
||||
|
||||
// create
|
||||
@@ -81,9 +83,11 @@ func Test_dal_crud_compose_record_update(t *testing.T) {
|
||||
helpers.AllowMeRecordCRUD(h)
|
||||
|
||||
ns := h.createNamespace("test")
|
||||
module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModelConfig{
|
||||
ConnectionID: 0,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModuleConfig{
|
||||
DAL: types.ModuleConfigDAL{
|
||||
ConnectionID: 0,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
},
|
||||
})
|
||||
|
||||
record := createRecordFromGenerics(ctx, t, "ok_record.json", ns.ID, module.ID)
|
||||
@@ -140,9 +144,11 @@ func Test_dal_crud_compose_record_delete(t *testing.T) {
|
||||
helpers.AllowMeRecordCRUD(h)
|
||||
|
||||
ns := h.createNamespace("test")
|
||||
module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModelConfig{
|
||||
ConnectionID: 0,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
module := createModuleFromGenerics(ctx, t, "ok_module.json", ns.ID, &types.ModuleConfig{
|
||||
DAL: types.ModuleConfigDAL{
|
||||
ConnectionID: 0,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
},
|
||||
})
|
||||
|
||||
record := createRecordFromGenerics(ctx, t, "ok_record.json", ns.ID, module.ID)
|
||||
|
||||
@@ -27,7 +27,7 @@ func Test_dal_crud_issues_compose_module_missing_sensitivity(t *testing.T) {
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present("$.response.moduleID")).
|
||||
Assert(jsonpath.Len("$.response.modelConfig.issues", 1)).
|
||||
Assert(jsonpath.Len("$.response.config.dal.issues", 1)).
|
||||
End()
|
||||
|
||||
dd := json.NewDecoder(rsp.Response.Body)
|
||||
@@ -42,7 +42,7 @@ func Test_dal_crud_issues_compose_module_missing_sensitivity(t *testing.T) {
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present("$.response.moduleID")).
|
||||
Assert(jsonpath.NotPresent("$.response.modelConfig.issues")).
|
||||
Assert(jsonpath.NotPresent("$.response.config.dal.issues")).
|
||||
End()
|
||||
|
||||
rsp = h.apiInit().
|
||||
@@ -54,7 +54,7 @@ func Test_dal_crud_issues_compose_module_missing_sensitivity(t *testing.T) {
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present("$.response.moduleID")).
|
||||
Assert(jsonpath.Len("$.response.modelConfig.issues", 1)).
|
||||
Assert(jsonpath.Len("$.response.config.dal.issues", 1)).
|
||||
End()
|
||||
|
||||
rsp = h.apiInit().
|
||||
@@ -84,7 +84,7 @@ func Test_dal_crud_issues_compose_module_field_missing_sensitivity(t *testing.T)
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present("$.response.moduleID")).
|
||||
Assert(jsonpath.Len("$.response.modelConfig.issues", 1)).
|
||||
Assert(jsonpath.Len("$.response.config.dal.issues", 1)).
|
||||
End()
|
||||
|
||||
dd := json.NewDecoder(rsp.Response.Body)
|
||||
@@ -98,7 +98,7 @@ func Test_dal_crud_issues_compose_module_field_missing_sensitivity(t *testing.T)
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present("$.response.moduleID")).
|
||||
Assert(jsonpath.NotPresent("$.response.modelConfig.issues")).
|
||||
Assert(jsonpath.NotPresent("$.response.config.dal.issues")).
|
||||
End()
|
||||
|
||||
rsp = h.apiInit().
|
||||
@@ -110,7 +110,7 @@ func Test_dal_crud_issues_compose_module_field_missing_sensitivity(t *testing.T)
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present("$.response.moduleID")).
|
||||
Assert(jsonpath.Len("$.response.modelConfig.issues", 1)).
|
||||
Assert(jsonpath.Len("$.response.config.dal.issues", 1)).
|
||||
End()
|
||||
|
||||
rsp = h.apiInit().
|
||||
@@ -143,7 +143,7 @@ func Test_dal_crud_issues_compose_module_nok_connection(t *testing.T) {
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present("$.response.moduleID")).
|
||||
Assert(jsonpath.Len("$.response.modelConfig.issues", 1)).
|
||||
Assert(jsonpath.Len("$.response.config.dal.issues", 1)).
|
||||
End()
|
||||
|
||||
dd := json.NewDecoder(rsp.Response.Body)
|
||||
@@ -170,7 +170,7 @@ func Test_dal_crud_issues_compose_module_nok_connection(t *testing.T) {
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present("$.response.moduleID")).
|
||||
Assert(jsonpath.NotPresent("$.response.modelConfig.issues")).
|
||||
Assert(jsonpath.NotPresent("$.response.config.dal.issues")).
|
||||
End()
|
||||
|
||||
rsp = h.apiInit().
|
||||
|
||||
@@ -21,9 +21,11 @@ func Test_dal_crud_issues_compose_record_nok_connection(t *testing.T) {
|
||||
ns := h.createNamespace("test")
|
||||
|
||||
connection := createConnectionFromGenerics(h.secCtx(), t, "nok_connection_connectivity.json")
|
||||
module := createModuleFromGenerics(h.secCtx(), t, "ok_module.json", ns.ID, &types.ModelConfig{
|
||||
ConnectionID: connection.ID,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
module := createModuleFromGenerics(h.secCtx(), t, "ok_module.json", ns.ID, &types.ModuleConfig{
|
||||
DAL: types.ModuleConfigDAL{
|
||||
ConnectionID: connection.ID,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
},
|
||||
})
|
||||
|
||||
h.apiInit().
|
||||
@@ -48,9 +50,11 @@ func Test_dal_crud_issues_compose_record_nok_model(t *testing.T) {
|
||||
ns := h.createNamespace("test")
|
||||
|
||||
connection := createConnectionFromGenerics(h.secCtx(), t, "ok_connection.json")
|
||||
module := createModuleFromGenerics(h.secCtx(), t, "nok_module_sensitivity_level.json", ns.ID, &types.ModelConfig{
|
||||
ConnectionID: connection.ID,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
module := createModuleFromGenerics(h.secCtx(), t, "nok_module_sensitivity_level.json", ns.ID, &types.ModuleConfig{
|
||||
DAL: types.ModuleConfigDAL{
|
||||
ConnectionID: connection.ID,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
},
|
||||
})
|
||||
|
||||
h.apiInit().
|
||||
@@ -75,9 +79,11 @@ func Test_dal_crud_issues_compose_record_ok(t *testing.T) {
|
||||
ns := h.createNamespace("test")
|
||||
|
||||
connection := createConnectionFromGenerics(h.secCtx(), t, "ok_connection.json")
|
||||
module := createModuleFromGenerics(h.secCtx(), t, "ok_module.json", ns.ID, &types.ModelConfig{
|
||||
ConnectionID: connection.ID,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
module := createModuleFromGenerics(h.secCtx(), t, "ok_module.json", ns.ID, &types.ModuleConfig{
|
||||
DAL: types.ModuleConfigDAL{
|
||||
ConnectionID: connection.ID,
|
||||
Capabilities: capabilities.FullCapabilities(),
|
||||
},
|
||||
})
|
||||
|
||||
h.apiInit().
|
||||
|
||||
@@ -129,7 +129,7 @@ func loadRequestFromScenarioWithConnection(t *testing.T, req string, connectionI
|
||||
aux := &composeTypes.Module{}
|
||||
require.NoError(t, json.Unmarshal([]byte(out), &aux))
|
||||
|
||||
aux.ModelConfig.ConnectionID = connectionID
|
||||
aux.Config.DAL.ConnectionID = connectionID
|
||||
|
||||
a, err := json.Marshal(aux)
|
||||
require.NoError(t, err)
|
||||
@@ -158,13 +158,13 @@ func createRecordFrom(ctx context.Context, t *testing.T, suite, name string, nam
|
||||
return record
|
||||
}
|
||||
|
||||
func createModuleFromCase(ctx context.Context, t *testing.T, name string, namespaceID uint64, config *composeTypes.ModelConfig) (module *composeTypes.Module) {
|
||||
func createModuleFromCase(ctx context.Context, t *testing.T, name string, namespaceID uint64, config *composeTypes.ModuleConfig) (module *composeTypes.Module) {
|
||||
return createModuleFrom(ctx, t, suiteFromT(t), name, namespaceID, config)
|
||||
}
|
||||
func createModuleFromGenerics(ctx context.Context, t *testing.T, name string, namespaceID uint64, config *composeTypes.ModelConfig) (module *composeTypes.Module) {
|
||||
func createModuleFromGenerics(ctx context.Context, t *testing.T, name string, namespaceID uint64, config *composeTypes.ModuleConfig) (module *composeTypes.Module) {
|
||||
return createModuleFrom(ctx, t, "generic", name, namespaceID, config)
|
||||
}
|
||||
func createModuleFrom(ctx context.Context, t *testing.T, suite, name string, namespaceID uint64, config *composeTypes.ModelConfig) (module *composeTypes.Module) {
|
||||
func createModuleFrom(ctx context.Context, t *testing.T, suite, name string, namespaceID uint64, config *composeTypes.ModuleConfig) (module *composeTypes.Module) {
|
||||
raw := loadRequestFrom(t, suite, name)
|
||||
|
||||
module = &composeTypes.Module{}
|
||||
@@ -173,7 +173,8 @@ func createModuleFrom(ctx context.Context, t *testing.T, suite, name string, nam
|
||||
module.NamespaceID = namespaceID
|
||||
|
||||
if config != nil {
|
||||
module.ModelConfig = *config
|
||||
// let's be careful not to override whole config
|
||||
module.Config.DAL = config.DAL
|
||||
}
|
||||
|
||||
module, err := composeService.DefaultModule.Create(ctx, module)
|
||||
|
||||
+11
-8
@@ -2,16 +2,19 @@
|
||||
"name": "internal_non_partitioned",
|
||||
"handle": "internal_non_partitioned",
|
||||
|
||||
"modelConfig": {
|
||||
"connectionID": "42",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
"config": {
|
||||
"dal": {
|
||||
"connectionID": "42",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"sensitivityLevel": "0",
|
||||
"usageDisclosure": "A"
|
||||
}
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"sensitivityLevel": "0",
|
||||
"usageDisclosure": "A"
|
||||
},
|
||||
|
||||
"fields": [
|
||||
{
|
||||
|
||||
+10
-9
@@ -2,15 +2,16 @@
|
||||
"name": "internal_non_partitioned",
|
||||
"handle": "internal_non_partitioned",
|
||||
|
||||
"modelConfig": {
|
||||
"connectionID": "0",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"sensitivityLevel": "0",
|
||||
"usageDisclosure": "A"
|
||||
"config": {
|
||||
"dal": {
|
||||
"connectionID": "0",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
"privacy": {
|
||||
"sensitivityLevel": "0",
|
||||
"usageDisclosure": "A"
|
||||
}
|
||||
},
|
||||
|
||||
"fields": [
|
||||
|
||||
@@ -2,15 +2,16 @@
|
||||
"name": "internal_non_partitioned",
|
||||
"handle": "internal_non_partitioned",
|
||||
|
||||
"modelConfig": {
|
||||
"connectionID": "0",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"sensitivityLevel": "42",
|
||||
"usageDisclosure": "A"
|
||||
"config": {
|
||||
"dal": {
|
||||
"connectionID": "0",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
"privacy": {
|
||||
"sensitivityLevel": "42",
|
||||
"usageDisclosure": "A"
|
||||
}
|
||||
},
|
||||
|
||||
"fields": [
|
||||
|
||||
@@ -2,15 +2,17 @@
|
||||
"name": "internal_non_partitioned",
|
||||
"handle": "internal_non_partitioned",
|
||||
|
||||
"modelConfig": {
|
||||
"connectionID": "0",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
"config": {
|
||||
"dal": {
|
||||
"connectionID": "0",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"sensitivityLevel": "42",
|
||||
"usageDisclosure": "A"
|
||||
"privacy": {
|
||||
"sensitivityLevel": "42",
|
||||
"usageDisclosure": "A"
|
||||
}
|
||||
},
|
||||
|
||||
"fields": [
|
||||
|
||||
+10
-9
@@ -2,15 +2,16 @@
|
||||
"name": "internal_non_partitioned",
|
||||
"handle": "internal_non_partitioned",
|
||||
|
||||
"modelConfig": {
|
||||
"connectionID": "0",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"sensitivityLevel": "0",
|
||||
"usageDisclosure": "A"
|
||||
"config": {
|
||||
"dal": {
|
||||
"connectionID": "0",
|
||||
"capabilities": [],
|
||||
"partitioned": false
|
||||
},
|
||||
"privacy": {
|
||||
"sensitivityLevel": "0",
|
||||
"usageDisclosure": "A"
|
||||
}
|
||||
},
|
||||
|
||||
"fields": [
|
||||
|
||||
Reference in New Issue
Block a user