3
0

Various DAL connection improvements & config reorg

This commit is contained in:
Denis Arh 2022-08-15 16:49:48 +02:00
parent f1908c9260
commit 554ae45ddf
18 changed files with 226 additions and 146 deletions

View File

@ -1357,18 +1357,6 @@ func moduleSystemFieldsToAttributes(mod *types.Module) (out dal.AttributeSet, er
// moduleFieldToAttribute converts the given module field to a DAL attribute
func moduleFieldToAttribute(f *types.ModuleField, conn *dal.ConnectionWrap) (out *dal.Attribute, err error) {
var (
// ensure JSON encoded record values always have ident to use
// either from the connection config or "values" as a failsafe
attribIdent = func() string {
var attribIdent = conn.Config.AttributeIdent
if len(attribIdent) > 0 {
return attribIdent
}
return "values"
}()
// generate dal.Codec for each attribute
// using encoding strategy for that attribute
// with failsafe on JSON RVS.
@ -1388,7 +1376,9 @@ func moduleFieldToAttribute(f *types.ModuleField, conn *dal.ConnectionWrap) (out
// defaulting to RecordValueSetJSON with
// default attribute ident from connection
return &dal.CodecRecordValueSetJSON{
Ident: attribIdent,
// ensure JSON encoded record values always have
// "values" as col ident as a failsafe
Ident: "values",
}
}
}

View File

@ -94,7 +94,7 @@ func makeTestModuleService(t *testing.T, mods ...any) *module {
ctx,
dal.MakeConnection(1, svc.store.ToDalConn(),
dal.ConnectionParams{},
dal.ConnectionConfig{ModelIdent: recordsTable, AttributeIdent: "values"},
dal.ConnectionConfig{ModelIdent: recordsTable},
),
true,
),

View File

@ -101,7 +101,7 @@ func makeTestRecordService(t *testing.T, mods ...any) *record {
ctx,
dal.MakeConnection(1, svc.store.ToDalConn(),
dal.ConnectionParams{},
dal.ConnectionConfig{ModelIdent: recordsTable, AttributeIdent: "values"},
dal.ConnectionConfig{ModelIdent: recordsTable},
),
true,
),
@ -109,7 +109,7 @@ func makeTestRecordService(t *testing.T, mods ...any) *record {
svc.dal = dalAux
// assuming store will alwats be RDBMS/SQLite and we can just run delete
// assuming store will always be RDBMS/SQLite and we can just run delete
//
// this could be done more "properly" by invoking DAL to truncate records
// but at the momment we need to provide the right model/module.

View File

@ -25,10 +25,6 @@ type (
// ident is considered valid if it matches one of the expressions
// or if the list of checks is empty
ModelIdentCheck []*regexp.Regexp
// If model attribute(s) do not specify
// @todo needs to be more explicit that this is for JSON encode attributes
AttributeIdent string
}
)

View File

@ -195,48 +195,49 @@ func NewDSNDriverConnectionConfig() DriverConnectionConfig {
}},
}
}
func NewHTTPDriverConnectionConfig() DriverConnectionConfig {
panic("not implemented NewHTTPDriverConnectionConfig")
return DriverConnectionConfig{
Type: "corteza::dal:connection:http",
Params: []DriverConnectionParam{{}},
}
}
func NewFederatedNodeDriverConnectionConfig() DriverConnectionConfig {
panic("not implemented NewFederatedNodeDriverConnectionConfig")
return DriverConnectionConfig{
Type: "corteza::dal:connection:federated-node",
Params: []DriverConnectionParam{{}},
}
}
func NewDSNConnection(dsn string) ConnectionParams {
return ConnectionParams{
Type: "corteza::dal:connection:dsn",
Params: map[string]any{
"dsn": dsn,
},
}
}
//func NewHTTPDriverConnectionConfig() DriverConnectionConfig {
// panic("not implemented NewHTTPDriverConnectionConfig")
// return DriverConnectionConfig{
// Type: "corteza::dal:connection:http",
// Params: []DriverConnectionParam{{}},
// }
//}
//func NewFederatedNodeDriverConnectionConfig() DriverConnectionConfig {
// panic("not implemented NewFederatedNodeDriverConnectionConfig")
// return DriverConnectionConfig{
// Type: "corteza::dal:connection:federated-node",
// Params: []DriverConnectionParam{{}},
// }
//}
func NewHTTPConnection(url string, headers, query map[string][]string) ConnectionParams {
return ConnectionParams{
Type: "corteza::dal:connection:http",
Params: map[string]any{
"url": url,
"headers": headers,
"query": query,
},
}
}
//func NewDSNConnection(dsn string) ConnectionParams {
// return ConnectionParams{
// Type: "corteza::dal:connection:dsn",
// Params: map[string]any{
// "dsn": dsn,
// },
// }
//}
func NewFederatedNodeCOnnection(url string, pairToken, authToken string) ConnectionParams {
return ConnectionParams{
Type: "corteza::dal:connection:federation-node",
Params: map[string]any{
"baseURL": url,
"pairToken": pairToken,
"authToken": authToken,
},
}
}
//func NewHTTPConnection(url string, headers, query map[string][]string) ConnectionParams {
// return ConnectionParams{
// Type: "corteza::dal:connection:http",
// Params: map[string]any{
// "url": url,
// "headers": headers,
// "query": query,
// },
// }
//}
//
//func NewFederatedNodeConnection(url string, pairToken, authToken string) ConnectionParams {
// return ConnectionParams{
// Type: "corteza::dal:connection:federation-node",
// Params: map[string]any{
// "baseURL": url,
// "pairToken": pairToken,
// "authToken": authToken,
// },
// }
//}

View File

@ -10,11 +10,6 @@ import (
"github.com/cortezaproject/corteza-server/system/types"
)
const (
DefaultComposeRecordTable = "compose_record"
DefaultComposeRecordValueCol = "values"
)
// Injects primary connection
func defaultDalConnection(ctx context.Context, s store.DalConnections) error {
conn, err := store.LookupDalConnectionByHandle(ctx, s, types.DalPrimaryConnectionHandle)
@ -39,10 +34,9 @@ func defaultDalConnection(ctx context.Context, s store.DalConnections) error {
},
Config: types.ConnectionConfig{
DAL: types.ConnectionConfigDAL{
ModelIdent: DefaultComposeRecordTable,
AttributeIdent: DefaultComposeRecordValueCol,
Operations: dal.FullOperations(),
DAL: &types.ConnectionConfigDAL{
ModelIdent: "compose_record",
Operations: dal.FullOperations(),
},
},

View File

@ -97,7 +97,7 @@ func NewConfig(in string) (*rdbms.ConnConfig, error) {
c.DriverName = in[:endOfSchema]
c.DataSourceName = in[endOfSchema+len(schemeDel):]
} else {
return nil, fmt.Errorf("expecting valid schema (mysql://) at the beginning of the DSN (%s)", in)
return nil, fmt.Errorf("expecting valid schema (mysql://) at the beginning of the DSN")
}
if pdsn, err := mysql.ParseDSN(c.DataSourceName); err != nil {

View File

@ -3,6 +3,7 @@ package postgres
import (
"context"
"database/sql"
"fmt"
"net/url"
"strings"
@ -80,6 +81,8 @@ func NewConfig(dsn string) (c *rdbms.ConnConfig, err error) {
if strings.HasPrefix(dsn, "postgres") {
scheme = u.Scheme
u.Scheme = validScheme
} else {
return nil, fmt.Errorf("expecting valid schema (postgres://) at the beginning of the DSN")
}
c = &rdbms.ConnConfig{

View File

@ -113,7 +113,7 @@ func NewConfig(in string) (*rdbms.ConnConfig, error) {
case strings.HasPrefix(in, debugSchema+schemaDel):
cfg.DriverName = debugSchema
default:
return nil, fmt.Errorf("expecting valid schema (sqlite3://) at the beginning of the DSN (%s)", in)
return nil, fmt.Errorf("expecting valid schema (sqlite3://) at the beginning of the DSN")
}
// reassemble DSN with base schema

View File

@ -13458,7 +13458,7 @@ func (s Store) TruncateLabels(ctx context.Context) error {
return s.Exec(ctx, labelTruncateQuery(s.Dialect))
}
// SearchLabels returns (filtered) set of Meta
// SearchLabels returns (filtered) set of Labels
//
// This function is auto-generated
func (s *Store) SearchLabels(ctx context.Context, f labelsType.LabelFilter) (set labelsType.LabelSet, _ labelsType.LabelFilter, err error) {

View File

@ -45,6 +45,7 @@ dal_connection: {
"read": description: "Read connection"
"update": description: "Update connection"
"delete": description: "Delete connection"
"dal-config.manage": description: "Manage DAL configuration"
}
}

View File

@ -9,7 +9,6 @@ import (
federationService "github.com/cortezaproject/corteza-server/federation/service"
federationTypes "github.com/cortezaproject/corteza-server/federation/types"
"github.com/cortezaproject/corteza-server/pkg/api"
"github.com/cortezaproject/corteza-server/pkg/dal"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/handle"
"github.com/cortezaproject/corteza-server/pkg/payload"
@ -36,6 +35,7 @@ type (
CanGrant bool `json:"canGrant"`
CanUpdateConnection bool `json:"canUpdateConnection"`
CanDeleteConnection bool `json:"canDeleteConnection"`
CanManageDalConfig bool `json:"canManageDalConfig"`
}
connectionSetPayload struct {
@ -48,6 +48,7 @@ type (
CanCreateDalConnection(context.Context) bool
CanUpdateDalConnection(context.Context, *types.DalConnection) bool
CanDeleteDalConnection(context.Context, *types.DalConnection) bool
CanManageDalConfigOnDalConnection(context.Context, *types.DalConnection) bool
}
connectionService interface {
@ -107,7 +108,12 @@ func (ctrl DalConnection) Create(ctx context.Context, r *request.DalConnectionCr
Config: r.Config,
}
return ctrl.svc.Create(ctx, connection)
res, err := ctrl.svc.Create(ctx, connection)
if err != nil {
return nil, err
}
return ctrl.makePayload(ctx, res), nil
}
func (ctrl DalConnection) Update(ctx context.Context, r *request.DalConnectionUpdate) (interface{}, error) {
@ -119,11 +125,21 @@ func (ctrl DalConnection) Update(ctx context.Context, r *request.DalConnectionUp
Config: r.Config,
}
return ctrl.svc.Update(ctx, connection)
res, err := ctrl.svc.Update(ctx, connection)
if err != nil {
return nil, err
}
return ctrl.makePayload(ctx, res), nil
}
func (ctrl DalConnection) Read(ctx context.Context, r *request.DalConnectionRead) (interface{}, error) {
return ctrl.svc.FindByID(ctx, r.ConnectionID)
res, err := ctrl.svc.FindByID(ctx, r.ConnectionID)
if err != nil {
return nil, err
}
return ctrl.makePayload(ctx, res), nil
}
func (ctrl DalConnection) Delete(ctx context.Context, r *request.DalConnectionDelete) (interface{}, error) {
@ -139,15 +155,19 @@ func (ctrl DalConnection) makeFilterPayload(ctx context.Context, connections typ
Filter: f,
Set: make([]*connectionPayload, 0, len(connections)),
}
for _, c := range connections {
c.Config.DAL.Operations = append(dal.OperationSet{}, c.Config.DAL.Operations...)
for _, c := range connections {
out.Set = append(out.Set, ctrl.makePayload(ctx, c))
}
return
}
// Make payload for dal-connection
//
// Payload is without connection params on the config prop
//
// An explicit call to /params
func (ctrl DalConnection) makePayload(ctx context.Context, c *types.DalConnection) *connectionPayload {
return &connectionPayload{
DalConnection: c,
@ -155,6 +175,7 @@ func (ctrl DalConnection) makePayload(ctx context.Context, c *types.DalConnectio
CanGrant: ctrl.connectionAc.CanGrant(ctx),
CanUpdateConnection: ctrl.connectionAc.CanUpdateDalConnection(ctx, c),
CanDeleteConnection: ctrl.connectionAc.CanDeleteDalConnection(ctx, c),
CanManageDalConfig: ctrl.connectionAc.CanManageDalConfigOnDalConnection(ctx, c),
}
}
@ -172,9 +193,9 @@ func (ctrl DalConnection) federatedNodeToConnection(f *federationTypes.Node) *ty
Handle: h,
Type: federationTypes.NodeResourceType,
Config: types.ConnectionConfig{
Connection: dal.NewFederatedNodeCOnnection(f.BaseURL, f.PairToken, f.AuthToken),
},
//Config: types.ConnectionConfig{
// Connection: dal.NewFederatedNodeConnection(f.BaseURL, f.PairToken, f.AuthToken),
//},
CreatedAt: f.CreatedAt,
CreatedBy: f.CreatedBy,

View File

@ -360,6 +360,11 @@ func (svc accessControl) List() (out []map[string]string) {
"any": types.DalConnectionRbacResource(0),
"op": "delete",
},
{
"type": types.DalConnectionResourceType,
"any": types.DalConnectionRbacResource(0),
"op": "dal-config.manage",
},
{
"type": types.ComponentResourceType,
"any": types.ComponentRbacResource(),
@ -884,6 +889,13 @@ func (svc accessControl) CanDeleteDalConnection(ctx context.Context, r *types.Da
return svc.can(ctx, "delete", r)
}
// CanManageDalConfigOnDalConnection checks if current user can manage dal configuration
//
// This function is auto-generated
func (svc accessControl) CanManageDalConfigOnDalConnection(ctx context.Context, r *types.DalConnection) bool {
return false && svc.can(ctx, "dal-config.manage", r)
}
// CanGrant checks if current user can manage system permissions
//
// This function is auto-generated
@ -1307,9 +1319,10 @@ func rbacResourceOperations(r string) map[string]bool {
}
case types.DalConnectionResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
"read": true,
"update": true,
"delete": true,
"dal-config.manage": true,
}
case types.ComponentResourceType:
return map[string]bool{

View File

@ -33,6 +33,7 @@ type (
CanReadDalConnection(context.Context, *types.DalConnection) bool
CanUpdateDalConnection(context.Context, *types.DalConnection) bool
CanDeleteDalConnection(context.Context, *types.DalConnection) bool
CanManageDalConfigOnDalConnection(context.Context, *types.DalConnection) bool
}
// Connection management on DAL Service
@ -69,7 +70,7 @@ func (svc *dalConnection) FindByID(ctx context.Context, ID uint64) (q *types.Dal
return DalConnectionErrNotAllowedToRead(rProps)
}
svc.proc(q)
svc.proc(ctx, q)
return nil
}()
return q, svc.recordAction(ctx, rProps, DalConnectionActionLookup, err)
@ -107,7 +108,7 @@ func (svc *dalConnection) Create(ctx context.Context, new *types.DalConnection)
if err = dalConnectionReplace(ctx, svc.store.ToDalConn(), svc.dal, new); err != nil {
return err
}
svc.proc(q)
svc.proc(ctx, q)
return
}()
@ -125,8 +126,6 @@ func (svc *dalConnection) Update(ctx context.Context, upd *types.DalConnection)
return DalConnectionErrNotFound(cProps)
}
svc.proc(old)
if !svc.ac.CanUpdateDalConnection(ctx, old) {
return DalConnectionErrNotAllowedToUpdate(cProps)
}
@ -139,11 +138,15 @@ func (svc *dalConnection) Update(ctx context.Context, upd *types.DalConnection)
{
if old.Type == types.DalPrimaryConnectionResourceType {
// when primary connection is updated,
// ignore configuration changes
// ignore connection & DAL config changes
//
// see Test_dal_connection_update_primary
// for more details
upd.Config = old.Config
upd.Config.DAL = old.Config.DAL
} else if upd.Config.DAL == nil {
upd.Config.DAL = old.Config.DAL
} else if !svc.ac.CanManageDalConfigOnDalConnection(ctx, old) {
return DalConnectionErrNotAllowedToUpdate()
}
}
@ -152,9 +155,14 @@ func (svc *dalConnection) Update(ctx context.Context, upd *types.DalConnection)
}
q = upd
defer svc.proc(q)
return dalConnectionReplace(ctx, svc.store.ToDalConn(), svc.dal, upd)
}()
if q != nil {
svc.proc(ctx, q)
}
return q, svc.recordAction(ctx, cProps, DalConnectionActionUpdate, err)
}
@ -247,7 +255,7 @@ func (svc *dalConnection) Search(ctx context.Context, filter types.DalConnection
return err
}
svc.proc(r...)
svc.proc(ctx, r...)
return nil
}()
return r, f, svc.recordAction(ctx, aProps, DalConnectionActionSearch, err)
@ -257,22 +265,32 @@ func (svc *dalConnection) ReloadConnections(ctx context.Context) (err error) {
return dalConnectionReload(ctx, svc.store, svc.dal)
}
func (svc *dalConnection) proc(connections ...*types.DalConnection) {
// proc is a helper function that processes the given connection set
// before connections are returned to the caller.
func (svc *dalConnection) proc(ctx context.Context, connections ...*types.DalConnection) {
for _, c := range connections {
svc.procPrimaryConnection(c)
svc.procDal(c)
svc.procDal(ctx, c)
svc.procLocale(c)
}
}
func (svc *dalConnection) procPrimaryConnection(c *types.DalConnection) {
if c.Type == types.DalPrimaryConnectionResourceType {
c.Config.Connection = dal.NewDSNConnection(svc.dbConf.DSN)
if c.Config.DAL == nil {
c.Config.DAL = &types.ConnectionConfigDAL{}
}
return
}
}
func (svc *dalConnection) procDal(c *types.DalConnection) {
func (svc *dalConnection) procDal(ctx context.Context, c *types.DalConnection) {
if !svc.ac.CanManageDalConfigOnDalConnection(ctx, c) {
c.Config.DAL = nil
return
}
ii := svc.dal.SearchConnectionIssues(c.ID)
if len(ii) == 0 {
c.Issues = nil
@ -318,6 +336,8 @@ func dalConnectionReplace(ctx context.Context, primary dal.Connection, dcm dalCo
isPrimary bool
connConfig dal.ConnectionConfig
conn dal.Connection
)
for _, c := range cc {
@ -326,7 +346,6 @@ func dalConnectionReplace(ctx context.Context, primary dal.Connection, dcm dalCo
connConfig = dal.ConnectionConfig{
SensitivityLevelID: c.Config.Privacy.SensitivityLevelID,
ModelIdent: c.Config.DAL.ModelIdent,
AttributeIdent: c.Config.DAL.AttributeIdent,
Label: c.Handle,
}
@ -339,18 +358,20 @@ func dalConnectionReplace(ctx context.Context, primary dal.Connection, dcm dalCo
}
}
if isPrimary {
// reuse primary connection
conn = primary
} else {
conn = nil
}
cw = dal.MakeConnection(
c.ID,
// When connection is primary (type) we use the primary connection
// passed in to the fn
func() dal.Connection {
if isPrimary {
return primary
}
return nil
}(),
c.Config.Connection,
conn,
dal.ConnectionParams{
Type: c.Config.DAL.Type,
Params: c.Config.DAL.Params,
},
connConfig,
c.Config.DAL.Operations...,
)

View File

@ -18,10 +18,14 @@ type (
Handle string `json:"handle"`
Type string `json:"type"`
Meta ConnectionMeta `json:"meta"`
// descriptions, notes, and other user-provided meta-data
Meta ConnectionMeta `json:"meta"`
// collection of configurations for various subsystems that
// use this connection and how it affects their behaviour
Config ConnectionConfig `json:"config"`
Issues []string `json:"issues,omitempty" db:"-"`
Issues []string `json:"issues,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
@ -33,46 +37,70 @@ type (
DeletedBy uint64 `json:"deletedBy,string,omitempty"`
}
ConnectionConfig struct {
Connection dal.ConnectionParams `json:"connection"`
Privacy ConnectionConfigPrivacy `json:"privacy"`
DAL ConnectionConfigDAL `json:"dal"`
// Meta ...................................................................
ConnectionMeta struct {
Name string `json:"name"`
Ownership string `json:"ownership"`
Location geolocation.Full `json:"location"`
Properties ConnectionMetaProperties `json:"properties"`
}
ConnectionProperties struct {
DataAtRestEncryption ConnectionPropertyMeta `json:"dataAtRestEncryption"`
DataAtRestProtection ConnectionPropertyMeta `json:"dataAtRestProtection"`
DataAtTransitEncryption ConnectionPropertyMeta `json:"dataAtTransitEncryption"`
DataRestoration ConnectionPropertyMeta `json:"dataRestoration"`
ConnectionMetaProperties struct {
DataAtRestEncryption ConnectionMetaProperty `json:"dataAtRestEncryption"`
DataAtRestProtection ConnectionMetaProperty `json:"dataAtRestProtection"`
DataAtTransitEncryption ConnectionMetaProperty `json:"dataAtTransitEncryption"`
DataRestoration ConnectionMetaProperty `json:"dataRestoration"`
}
ConnectionPropertyMeta struct {
ConnectionMetaProperty struct {
Enabled bool `json:"enabled"`
Notes string `json:"notes"`
}
ConnectionMeta struct {
Location geolocation.Full `json:"location"`
Ownership string `json:"ownership"`
Name string `json:"name"`
// Config .................................................................
ConnectionConfig struct {
// DAL configuration
// using ptr to allow nil values (when dealing with access-controlled data)
DAL *ConnectionConfigDAL `json:"dal,omitempty"`
// Privacy configuration
Privacy ConnectionConfigPrivacy `json:"privacy"`
}
ConnectionConfigPrivacy struct {
// Sets max-allowed data-sensitivity level for this connection
//
// Fields of the modules using this connection should have equal or
// lower sensitivity level
SensitivityLevelID uint64 `json:"sensitivityLevelID,string,omitempty"`
}
// ConnectionConfigDAL a set of connection parameters
// and model configuration
ConnectionConfigDAL struct {
Properties ConnectionProperties `json:"properties"`
// type of connection
Type string `json:"type"`
// parameters for th connection
Params map[string]any `json:"params"`
// @note operations, for now, will only be available on connections
// with a fallback on modules
Operations dal.OperationSet `json:"operations"`
ModelIdent string `json:"modelIdent"`
AttributeIdent string `json:"attributeIdent"`
// ident to be used when generating models from modules using this connection
// it can use {{module}} and {{namespace}} as placeholders
ModelIdent string `json:"modelIdent"`
// set of regular-expression strings that will be used to match against
// generated model identifiers
ModelIdentCheck []string `json:"modelIdentCheck"`
}
// ........................................................................
DalConnectionFilter struct {
ConnectionID []uint64 `json:"connectionID,string"`
Handle string `json:"handle"`

View File

@ -139,7 +139,6 @@ func initSvc(ctx context.Context, d driver) (dalService, error) {
cm := dal.ConnectionConfig{
ModelIdent: c.Config.DAL.ModelIdent,
AttributeIdent: c.Config.DAL.AttributeIdent,
SensitivityLevelID: c.Config.Privacy.SensitivityLevelID,
Label: c.Handle,
}
@ -149,7 +148,17 @@ func initSvc(ctx context.Context, d driver) (dalService, error) {
return nil, err
}
err = svc.ReplaceConnection(ctx, dal.MakeConnection(c.ID, nil, c.Config.Connection, cm, dal.FullOperations()...), true)
err = svc.ReplaceConnection(
ctx,
dal.MakeConnection(
c.ID,
nil,
dal.ConnectionParams{},
cm,
dal.FullOperations()...,
),
true,
)
if err != nil {
return nil, err
}

View File

@ -256,11 +256,14 @@ func (h helper) createDalConnection(res *types.DalConnection) *types.DalConnecti
if res.Config.DAL.ModelIdent == "" {
res.Config.DAL.ModelIdent = "compose_records"
}
if res.Config.DAL.AttributeIdent == "" {
res.Config.DAL.AttributeIdent = "values"
}
if res.Config.Connection.Params == nil {
res.Config.Connection = dal.NewDSNConnection("sqlite3://file::memory:?cache=shared&mode=memory")
if res.Config.DAL.Params == nil {
res.Config.DAL = &types.ConnectionConfigDAL{
Type: "corteza::dal:connection:dsn",
Params: map[string]any{
"dsn": "sqlite3://file::memory:?cache=shared&mode=memory",
},
}
}
if len(res.Config.DAL.Operations) == 0 {
@ -295,13 +298,10 @@ func makeConnectionDefinition(dsn string) *types.DalConnection {
ID: id.Next(),
Type: types.DalConnectionResourceType,
Config: types.ConnectionConfig{
DAL: types.ConnectionConfigDAL{
ModelIdent: "compose_record",
AttributeIdent: "values",
Operations: dal.FullOperations(),
DAL: &types.ConnectionConfigDAL{
ModelIdent: "compose_record",
Operations: dal.FullOperations(),
},
Connection: dal.NewDSNConnection(dsn),
},
}
}

View File

@ -60,11 +60,14 @@ func (h helper) createDalConnection(res *types.DalConnection) *types.DalConnecti
if res.Config.DAL.ModelIdent == "" {
res.Config.DAL.ModelIdent = "compose_records_{{namespace}}_{{module}}"
}
if res.Config.DAL.AttributeIdent == "" {
res.Config.DAL.AttributeIdent = "values"
}
if res.Config.Connection.Params == nil {
res.Config.Connection = dal.NewDSNConnection("sqlite3://file::memory:?cache=shared&mode=memory")
if res.Config.DAL == nil {
res.Config.DAL = &types.ConnectionConfigDAL{
Type: "corteza::dal:connection:dsn",
Params: map[string]any{
"dsn": "sqlite3://file::memory:?cache=shared&mode=memory",
},
}
}
if len(res.Config.DAL.Operations) == 0 {