diff --git a/README.md b/README.md index 3310830..7192a38 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # Docugraphy Docugraphy is a framework for modeling a data structure consisting of a wide, although sparsely filled, records. -The assumption is that the content filling the structure takes many forms, that are quasi-defined subsets of the available attributes/columns. \ No newline at end of file +The assumption is that the content filling the structure takes many forms, that are quasi-defined subsets of the available attributes/columns. + + ## Schema + + \ No newline at end of file diff --git a/model/structs.go b/model/structs.go index fdf7686..5255971 100644 --- a/model/structs.go +++ b/model/structs.go @@ -11,18 +11,22 @@ const ( Decommisioned // Removed from PROD ) +type ImplementationStatusDictionary struct { + Id ImplementationStatus `sql:",pk"` + Status string // Arbitrary name/tag for the source system + Description string // What the source system represents, it's job/competence +} + //Definition of a source system that produces data feeding the wide-row. type SourceSystem struct { - Id uint32 `json:"-"` - Name string `sql:",unique"` // Arbitrary name/tag for the source system + Name string `sql:",pk"` // Arbitrary name/tag for the source system Description string // What the source system represents, it's job/competence } // An event type is a data structure consisting of a subset of fields available in the wide-row structure. // This structure represents the canonical definition of the event type. type EventType struct { - Id uint64 `json:"-"` - Name string `sql:",unique"` // The name of a event_type according to the wide-row design + Name string `sql:",pk"` // The name of a event_type according to the wide-row design RecommendedUse string // The explanation of how to use this event type in terms of its universal business definition Status ImplementationStatus //What is the status of the event type on a receiving point (data lake) } @@ -32,18 +36,17 @@ type EventTypeImplementation struct { PreciseUse string //The explanation of how to use this event type in terms of its business definition according to a certain source system Status ImplementationStatus //What is the status of the event type on a sending point (source system) - EventTypeId uint64 `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` // Reference to the canonical definition of an event type + EventTypeName string `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` // Reference to the canonical definition of an event type EventType *EventType - SourceSystemId uint32 `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` // Reference to a source system that the implementation refers to + SourceSystemName string `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` // Reference to a source system that the implementation refers to SourceSystem *SourceSystem } // Definition of a field/attribute within the wide-row structure. // This structure represents the canonical definition of the field. type Field struct { - Id uint64 `json:"-"` - Name string `sql:",unique"` // The name of a field according to the wide-row design + Name string `sql:",pk"` // The name of a field according to the wide-row design Type string // Data type of the field RecommendedUse string // The explanation of how to use this field in terms of its universal business definition Status ImplementationStatus //What is the status of the field on a receiving point (data lake) @@ -54,11 +57,12 @@ type FieldImplementation struct { PreciseUse string //The explanation of how to use this field in terms of its business definition according to a certain source system Status ImplementationStatus //What is the status of the field on a sending point (source system) - FieldId uint64 `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` + FieldName string `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` Field *Field - SourceSystemId uint32 `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` - SourceSystem *SourceSystem + EventTypeName string `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` + SourceSystemName string `sql:"on_delete:RESTRICT, on_update: CASCADE, pk"` + EventTypeImplementation *EventTypeImplementation } // Definition of a value from a restricted list that applies for a certain field (and source system) diff --git a/repository/common.go b/repository/common.go index 2952e0a..acff544 100644 --- a/repository/common.go +++ b/repository/common.go @@ -10,6 +10,21 @@ type Repository interface { Connect() Disconnect() error SetupSchema() error + GetSourceSystems() ([]model.SourceSystem, error) + GetEventTypes() ([]model.EventType, error) + GetFields() ([]model.Field, error) + GetEventTypeImplementations(sourceSystemName string) ([]model.EventTypeImplementation, error) + GetFieldImplementations(sourceSystemName string, fieldName string) ([]model.FieldImplementation, error) + AddSourceSystem(sourceSystem *model.SourceSystem) error + AddEventType(eventType *model.EventType) error + AddField(field *model.Field) error + AddEventTypeImplementation(eventTypeImplementation *model.EventTypeImplementation) error + AddFieldImplementation(fieldImplementation *model.FieldImplementation) error + + ChangeStatusOfEventType(eventTypeName string, status model.ImplementationStatus) error + ChangeStatusOfField(fieldName string, status model.ImplementationStatus) error + ChangeStatusOfEventTypeImplementation(eventTypeName string, sourceSystemName string, status model.ImplementationStatus) error + ChangeStatusOfFieldImplementation(fieldName string, eventTypeName string, sourceSystem string, status model.ImplementationStatus) error } diff --git a/repository/postgres/create_repo.go b/repository/postgres/create_repo.go index bf832b1..4573482 100644 --- a/repository/postgres/create_repo.go +++ b/repository/postgres/create_repo.go @@ -31,6 +31,7 @@ func (pr *Repository) SetupSchema() error { (*model.Field)(nil), (*model.FieldImplementation)(nil), (*model.RestrictedValue)(nil), + (*model.ImplementationStatusDictionary)(nil), } { err := pr.Connection.CreateTable(entity, &orm.CreateTableOptions{ FKConstraints: true, @@ -54,6 +55,107 @@ func (pr *Repository) GetSourceSystems() ([]model.SourceSystem, error) { return sourceSystem, nil } +func (pr *Repository) GetEventTypes() ([]model.EventType, error) { + var eventType []model.EventType + + err := pr.Connection.Model(&eventType).Select() + if err != nil { + return nil, err + } + return eventType, nil +} + +func (pr *Repository) getEventType(eventTypeName string) (model.EventType, error) { + eventType := model.EventType{} + + err := pr.Connection.Model(&eventType). + Where("event_type.name = ?", eventTypeName). + Select() + if err != nil { + return eventType, err + } + return eventType, nil +} + +func (pr *Repository) GetFields() ([]model.Field, error) { + var fields []model.Field + + err := pr.Connection.Model(&fields).Select() + if err != nil { + return nil, err + } + return fields, nil +} + +func (pr *Repository) getField(fieldName string) (model.Field, error) { + field := model.Field{} + + err := pr.Connection.Model(&field). + Where("field.name = ?", fieldName). + Select() + if err != nil { + return field, err + } + return field, nil +} + +func (pr *Repository) GetEventTypeImplementations(sourceSystemName string) ([]model.EventTypeImplementation, error) { + var eventTypeImplementations []model.EventTypeImplementation + + err := pr.Connection. + Model(&eventTypeImplementations). + Where("event_type_implementation.source_system = ?", sourceSystemName). + Select() + if err != nil { + return nil, err + } + return eventTypeImplementations, nil +} + +func (pr *Repository) getEventTypeImplementation(sourceSystemName string, eventTypeName string) (model.EventTypeImplementation, error) { + eventTypeImplementation := model.EventTypeImplementation{} + + err := pr.Connection. + Model(&eventTypeImplementation). + Where("event_type_implementation.source = ?", sourceSystemName). + Where("event_type_implementation.event_type_name = ?", eventTypeName). + Select() + if err != nil { + return eventTypeImplementation, err + } + return eventTypeImplementation, nil +} + +func (pr *Repository) GetFieldImplementations(sourceSystemName string, eventTypeName string) ([]model.FieldImplementation, error) { + var fieldImplementations []model.FieldImplementation + + err := pr.Connection. + Model(&fieldImplementations). + Column("event_type_implementation"). + Where("event_type_implementation.source = ?", sourceSystemName). + Where("event_type_implementation.event_type_name = ?", eventTypeName). + Select("field.*") + if err != nil { + return nil, err + } + return fieldImplementations, nil +} + +func (pr *Repository) getFieldImplementation(sourceSystemName string, eventTypeName string, fieldName string) (model.FieldImplementation, error) { + fieldImplementation := model.FieldImplementation{} + + err := pr.Connection. + Model(&fieldImplementation). + Where("field_implementation.source = ?", sourceSystemName). + Where("field_implementation.event_type_name = ?", eventTypeName). + Where("field_implementation.field_name = ?", fieldName). + Select() + if err != nil { + return fieldImplementation, err + } + return fieldImplementation, nil +} + func (pr *Repository) AddSourceSystem(sourceSystem *model.SourceSystem) error { err := pr.Connection.Insert(sourceSystem) if err != nil { @@ -62,3 +164,99 @@ func (pr *Repository) AddSourceSystem(sourceSystem *model.SourceSystem) error { log.Println("Inserted new Source System: ", sourceSystem.Name) return nil } + +func (pr *Repository) AddEventType(eventType *model.EventType) error { + err := pr.Connection.Insert(eventType) + if err != nil { + return err + } + log.Println("Inserted new Event Type: ", eventType.Name) + return nil +} + +func (pr *Repository) AddField(field *model.Field) error { + err := pr.Connection.Insert(field) + if err != nil { + return err + } + log.Println("Inserted new Field: ", field.Name) + return nil +} + +func (pr *Repository) AddEventTypeImplementation(eventTypeImplementation *model.EventTypeImplementation) error { + err := pr.Connection.Insert(eventTypeImplementation) + if err != nil { + return err + } + log.Println("Inserted new Event Type Implementation with Event Type: ", + eventTypeImplementation.EventTypeName, + ", and source system: ", + eventTypeImplementation.SourceSystemName) + return nil +} + +func (pr *Repository) AddFieldImplementation(fieldImplementation *model.FieldImplementation) error { + err := pr.Connection.Insert(fieldImplementation) + if err != nil { + return err + } + log.Println("Inserted new Event Type Implementation with Event Type: ", + fieldImplementation.EventTypeName, + ", and field: ", + fieldImplementation.FieldName, + ", and source system: ", + fieldImplementation.SourceSystemName) + return nil +} + +func (pr *Repository) ChangeStatusOfEventType(eventTypeName string, status model.ImplementationStatus) error { + eventType, err := pr.getEventType(eventTypeName) + if err != nil { + return err + } + eventType.Status = status + err = pr.Connection.Update(&eventType) + if err != nil { + return err + } + return nil +} + +func (pr *Repository) ChangeStatusOfField(fieldName string, status model.ImplementationStatus) error { + field, err := pr.getField(fieldName) + if err != nil { + return err + } + field.Status = status + err = pr.Connection.Update(&field) + if err != nil { + return err + } + return nil +} + +func (pr *Repository) ChangeStatusOfEventTypeImplementation(eventTypeName string, sourceSystem string, status model.ImplementationStatus) error { + eventTypeImplementation, err := pr.getEventTypeImplementation(eventTypeName, sourceSystem) + if err != nil { + return err + } + eventTypeImplementation.Status = status + err = pr.Connection.Update(&eventTypeImplementation) + if err != nil { + return err + } + return nil +} + +func (pr *Repository) ChangeStatusOfFieldImplementation(fieldName string, eventTypeName string, sourceSystem string, status model.ImplementationStatus) error { + fieldImplementation, err := pr.getFieldImplementation(fieldName, eventTypeName, sourceSystem) + if err != nil { + return err + } + fieldImplementation.Status = status + err = pr.Connection.Update(&fieldImplementation) + if err != nil { + return err + } + return nil +} diff --git a/repository/repo.go b/repository/repo.go index d43bd76..c092579 100644 --- a/repository/repo.go +++ b/repository/repo.go @@ -7,10 +7,10 @@ import ( "fmt" ) -var dbRepo Repository +var DbRepo Repository func Create() error { - err := dbRepo.SetupSchema() + err := DbRepo.SetupSchema() return err } @@ -18,19 +18,19 @@ func Connect() error { var err error = nil switch dbType := config.GetConfig().DbType; dbType { case TypeNamePostgres: - dbRepo = postgres.Build() + DbRepo = postgres.Build() default: err = fmt.Errorf("Unknown database id %s\n", dbType) return err } - dbRepo.Connect() + DbRepo.Connect() return err } func GetSourceSystems() ([]model.SourceSystem, error) { - return dbRepo.GetSourceSystems() + return DbRepo.GetSourceSystems() } func AddSourceSystem(sourceSystem *model.SourceSystem) error { - return dbRepo.AddSourceSystem(sourceSystem) + return DbRepo.AddSourceSystem(sourceSystem) } diff --git a/schema.drawio b/schema.drawio new file mode 100644 index 0000000..d0ea0b6 --- /dev/null +++ b/schema.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file