Files
metl/action.go
2021-05-23 22:15:30 -06:00

248 lines
5.5 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"
"github.com/google/uuid"
)
type Action interface {
Run(row ContentRow) error
//publishRow(row ContentRow) error
//publishErrorRow(row ContentRow) error
//Start()
//Finish()
Status() ActionStatus
Validate() error
GetActionID() uuid.UUID
GetActionConfig() ActionConfig
}
type Schema struct {
Columns []ColumnDefinition
}
type ColumnDefinition struct {
Name string
ID uuid.UUID
Type DataType
DefaultValue string
}
type ContentRow struct {
Schema *Schema
Values map[uuid.UUID]string
Raw string
Source *uuid.UUID
}
type ActionConfig struct {
ActionID uuid.UUID
Type ActionType
OutputSchema *Schema
Inputs []InputDefinition
}
type InputDefinition struct {
InputSchema *Schema
ActionID *uuid.UUID
// TODO: decide if input types exist
}
type ActionStatus struct {
State StateValue
ExpectedRows int64
HandledRows int64
}
// DataType - Custom type to hold value for data type ranging from 1-5
type DataType int
// Declare related constants for each datatype starting with index 1
const (
String DataType = iota + 1
Integer
Float
Date
DateTime
)
// String - Creating common behavior give the type a String function
func (d DataType) String() string {
return [...]string{"String", "Integer", "Float", "Date", "DateTime"}[d-1]
}
// EnumIndex - Creating common behavior give the type a EnumIndex function
func (d DataType) EnumIndex() int {
return int(d)
}
// MarshalJSON marshals the enum as a quoted json string
func (s DataType) MarshalJSON() ([]byte, error) {
buffer := bytes.NewBufferString(`"`)
buffer.WriteString(s.String())
buffer.WriteString(`"`)
return buffer.Bytes(), nil
}
// UnmarshalJSON unmashals a quoted json string to the enum value
func (s *DataType) UnmarshalJSON(b []byte) error {
var j string
err := json.Unmarshal(b, &j)
if err != nil {
return err
}
// Note that if the string cannot be found then it will be set to the zero value, 'String' in this case.
var toID = map[string]DataType{
"String": String,
"Integer": Integer,
"Float": Float,
"Date": Date,
"DateTime": DateTime,
}
*s = toID[j]
return nil
}
func ValidateDataType(in string, dataType DataType) (bool, error) {
switch dataType {
case String:
return ValidStringDataType(in), nil
case Integer:
return ValidIntegerDataType(in)
case Float:
return ValidFloatDataType(in)
case Date:
return ValidDateDataType(in)
case DateTime:
return ValidDateTimeDataType(in)
default:
return false, nil
}
}
func ValidStringDataType(in string) bool {
return true
}
func ValidIntegerDataType(in string) (bool, error) {
i, err := strconv.ParseInt(in, 10, 64)
if err != nil {
return false, err
}
return strings.EqualFold(in, fmt.Sprintf("%v", i)), nil
}
func ValidFloatDataType(in string) (bool, error) {
i, err := strconv.ParseFloat(in, 64)
if err != nil {
return false, err
}
return strings.EqualFold(in, fmt.Sprintf("%v", i)), nil
}
func ValidDateDataType(in string) (bool, error) {
// TODO: implement
return false, nil
}
func ValidDateTimeDataType(in string) (bool, error) {
// TODO: implement
return false, nil
}
// ActionType - Custom type to hold value for data type ranging from 1-5
type ActionType int
const (
StdIn ActionType = iota + 1
ModifyColumn
StdOut
)
// String - Creating common behavior give the type a String function
func (d ActionType) String() string {
return [...]string{"StdIn", "ModifyColumn", "StdOut"}[d-1]
}
// EnumIndex - Creating common behavior give the type a EnumIndex function
func (d ActionType) EnumIndex() int {
return int(d)
}
// MarshalJSON marshals the enum as a quoted json string
func (s ActionType) MarshalJSON() ([]byte, error) {
buffer := bytes.NewBufferString(`"`)
buffer.WriteString(s.String())
buffer.WriteString(`"`)
return buffer.Bytes(), nil
}
// UnmarshalJSON unmashals a quoted json string to the enum value
func (s *ActionType) UnmarshalJSON(b []byte) error {
var j string
err := json.Unmarshal(b, &j)
if err != nil {
return err
}
// Note that if the string cannot be found then it will be set to the zero value, 'String' in this case.
var toID = map[string]ActionType{
"StdIn": StdIn,
"ModifyColumn": ModifyColumn,
"StdOut": StdOut,
}
*s = toID[j]
return nil
}
// StateValue - Custom type to hold value for data type ranging from 1-5
type StateValue int
// Declare related constants for each datatype starting with index 1
const (
NotStarted StateValue = iota + 1
Paused
Running
Finished
)
// String - Creating common behavior give the type a String function
func (d StateValue) String() string {
return [...]string{"NotStarted", "Paused", "Running", "Finished"}[d-1]
}
// EnumIndex - Creating common behavior give the type a EnumIndex function
func (d StateValue) EnumIndex() int {
return int(d)
}
// MarshalJSON marshals the enum as a quoted json string
func (s StateValue) MarshalJSON() ([]byte, error) {
buffer := bytes.NewBufferString(`"`)
buffer.WriteString(s.String())
buffer.WriteString(`"`)
return buffer.Bytes(), nil
}
// UnmarshalJSON unmashals a quoted json string to the enum value
func (s *StateValue) UnmarshalJSON(b []byte) error {
var j string
err := json.Unmarshal(b, &j)
if err != nil {
return err
}
// Note that if the string cannot be found then it will be set to the zero value, 'String' in this case.
var toID = map[string]StateValue{
"NotStarted": NotStarted,
"Paused": Paused,
"Running": Running,
"Finished": Finished,
}
*s = toID[j]
return nil
}