package main import ( "database/sql" "fmt" ) // Web type NavItem struct { Caption string Destination string } func NewNavItem(caption, destination string) NavItem { return NavItem{caption, destination} } type Stylename string func NewStyleItemList(stylenames ...Stylename) []Stylename { return stylenames } type TableColumns []string type TableRow struct { Columns TableColumns Id int } type Table struct { Collumns TableColumns Rows []TableRow } func (t Table) FilterColumns(indices ...int) (Table, error) { table := Table{} for _, i := range indices { if i < 0 || i >= len(t.Collumns) { return table, fmt.Errorf("Index out of bounds: expected: 0-%v: actual: %v", len(t.Collumns), i) } } table.Collumns = make(TableColumns, len(indices)) for i, I := range indices { table.Collumns[i] = t.Collumns[I] } table.Rows = make([]TableRow, len(t.Rows)) for i, r := range t.Rows { table.Rows[i] = TableRow{} table.Rows[i].Id = r.Id table.Rows[i].Columns = make(TableColumns, len(indices)) for j, I := range indices { table.Rows[i].Columns[j] = t.Rows[i].Columns[I] } } return table, nil } type HtmlElement interface { HtmlTag() string } type InputField struct { Id string Type string Label string Name string Value string IsRequired bool } func (i *InputField) HtmlTag() string { return "input" } type Option struct { Caption string Value string Selected bool } type Select struct { Id string Label string Name string Options []*Option IsRequired bool } func (s *Select) HtmlTag() string { return "select" } type TextArea struct { Id string Label string Name string Value string IsRequired bool } func (t *TextArea) HtmlTag() string { return "textarea" } type Form struct { RowId int Table string Elements []HtmlElement } // Database type Location struct { Id sql.NullInt64 Parent sql.NullInt64 Name sql.NullString Description sql.NullString Connection *Connection } func (l *Location) ToForm() (Form, error) { form := Form{} if l.Id.Valid { form.RowId = int(l.Id.Int64) } form.Table = "locations" form.Elements = make([]HtmlElement, 3) lOptions := make([]*Option, 0) locations, err := l.Connection.QueryLocations() if err == nil { lOptions, err = LocationsToOption(locations, l) for i, o := range lOptions { if o == nil { fmt.Println(i) } } } if err != nil { fmt.Println(err) } parentInput := &Select{ Id: "parent", Label: "Übergeordneter Ort", Name: "parent", Options: lOptions, } nameInput := &InputField{ Id: "name", Type: "text", Label: "Name", Name: "name", } descInput := &InputField{ Id: "description", Type: "text", Label: "Beschreibung", Name: "description", } form.Elements[0] = parentInput if l.Name.Valid { nameInput.Value = fmt.Sprintf("%v", l.Name.String) } else { nameInput.Value = "" } form.Elements[1] = nameInput if l.Description.Valid { descInput.Value = fmt.Sprintf("%v", l.Description.String) } else { descInput.Value = "" } form.Elements[2] = descInput return form, nil } func (l *Location) ToTableRow() TableRow { columns := make(TableColumns, 3) tr := TableRow{} var path string if l.Id.Valid { columns[0] = fmt.Sprintf("%d", l.Id.Int64) tr.Id = int(l.Id.Int64) path, _ = l.Connection.QueryLocationFullPath(l.Id.Int64) } else { columns[0] = "NULL" tr.Id = -1 } columns[1] = path if l.Description.Valid { columns[2] = l.Description.String } else { columns[2] = "NULL" } tr.Columns = columns return tr } func (l *Location) GetParent() *Location { return nil } func (l *Location) FullPath() (string, error) { return l.Connection.QueryLocationFullPath(l.Id.Int64) } type Container struct { Id sql.NullInt64 Name sql.NullString } func (c *Container) ToForm() Form { form := Form{} if c.Id.Valid { form.RowId = int(c.Id.Int64) } else { return form } form.Table = "containers" form.Elements = make([]HtmlElement, 1) nameInput := InputField{ "name", "text", "Name", "name", "", true, } if c.Name.Valid { nameInput.Value = c.Name.String } form.Elements[0] = &nameInput return form } func (c *Container) ToTableRow() TableRow { columns := make(TableColumns, 2) tr := TableRow{} if c.Id.Valid { columns[0] = fmt.Sprintf("%d", c.Id.Int64) tr.Id = int(c.Id.Int64) } else { columns[0] = "NULL" tr.Id = -1 } if c.Name.Valid { columns[1] = c.Name.String } else { columns[1] = "NULL" } tr.Columns = columns return tr } type Part struct { Id sql.NullInt64 Name sql.NullString Tags sql.NullString Location Location Container Container Connection *Connection } func (p *Part) ToTableRow() TableRow { columns := make(TableColumns, 5) tr := TableRow{} if p.Id.Valid { columns[0] = fmt.Sprintf("%d", p.Id.Int64) tr.Id = int(p.Id.Int64) } else { columns[0] = "NULL" tr.Id = -1 } if p.Name.Valid { columns[1] = p.Name.String } else { columns[1] = "NULL" } if p.Tags.Valid { columns[2] = p.Tags.String } else { columns[2] = "NULL" } if p.Location.Id.Valid { fullPath, err := p.Connection.QueryLocationFullPath(p.Location.Id.Int64) if err != nil { fmt.Println(err) } columns[3] = fullPath } else { columns[3] = "NULL" } if p.Container.Name.Valid { columns[4] = p.Container.Name.String } else { columns[4] = "NULL" } tr.Columns = columns return tr } func (p *Part) ToForm() Form { form := Form{} if p.Id.Valid { form.RowId = int(p.Id.Int64) } else { return form } form.Table = "parts" form.Elements = make([]HtmlElement, 4) nameInput := InputField{ "name", "text", "Name", "name", "", true, } if p.Name.Valid { nameInput.Value = p.Name.String } tagsInput := TextArea{ "tags", "Tags", "tags", "", true, } if p.Tags.Valid { tagsInput.Value = p.Tags.String } lOptions := make([]*Option, 0) locations, err := p.Connection.QueryLocations() if err == nil { lOptions, err = LocationsToOption(locations, &p.Location) for i, o := range lOptions { if o == nil { fmt.Println(i) } } } if err != nil { fmt.Println(err) } locationInput := Select{ Id: "location", Label: "Ort", Name: "location", Options: lOptions, } cOptions := make([]*Option, 0) containers, err := p.Connection.QueryContainers() if err == nil { cOptions, err = ContainersToOption(containers, &p.Container) for i, o := range lOptions { if o == nil { fmt.Println(i) } } } containerInput := Select{ Id: "container", Label: "Behälter", Name: "container", Options: cOptions, } form.Elements[0] = &nameInput form.Elements[1] = &tagsInput form.Elements[2] = &locationInput form.Elements[3] = &containerInput return form } // Interfaces type DatabaseType interface { ToTableRow() TableRow }