13 changed files with 260 additions and 10 deletions
			
			
		- 
					4app/api/bridges.go
- 
					83app/api/presets.go
- 
					4app/config/driver.go
- 
					9app/config/repo.go
- 
					1app/server.go
- 
					2cmd/bridgetest/main.go
- 
					2cmd/goose/main.go
- 
					10internal/drivers/provider.go
- 
					2internal/mysql/bridgerepo.go
- 
					99internal/mysql/presetrepo.go
- 
					26models/colorpreset.go
- 
					17scripts/20210523175111_color_preset.sql
- 
					11scripts/20210523175425_color_preset_name.sql
| @ -0,0 +1,83 @@ | |||||
|  | package api | ||||
|  | 
 | ||||
|  | import ( | ||||
|  | 	"git.aiterp.net/lucifer/new-server/app/config" | ||||
|  | 	"git.aiterp.net/lucifer/new-server/models" | ||||
|  | 	"github.com/gin-gonic/gin" | ||||
|  | ) | ||||
|  | 
 | ||||
|  | func ColorPresets(r gin.IRoutes) { | ||||
|  | 	r.GET("", handler(func(c *gin.Context) (interface{}, error) { | ||||
|  | 		return config.ColorPresetRepository().FetchAll(ctxOf(c)) | ||||
|  | 	})) | ||||
|  | 
 | ||||
|  | 	r.GET("/:id", handler(func(c *gin.Context) (interface{}, error) { | ||||
|  | 		return config.ColorPresetRepository().Find(ctxOf(c), intParam(c, "id")) | ||||
|  | 	})) | ||||
|  | 
 | ||||
|  | 	r.POST("", handler(func(c *gin.Context) (interface{}, error) { | ||||
|  | 		var body struct { | ||||
|  | 			Name        string `json:"name"` | ||||
|  | 			ColorString string `json:"colorString"` | ||||
|  | 		} | ||||
|  | 		err := parseBody(c, &body) | ||||
|  | 		if err != nil { | ||||
|  | 			return nil, err | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		newColor, err := models.ParseColorValue(body.ColorString) | ||||
|  | 		if err != nil { | ||||
|  | 			return nil, err | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		preset := models.ColorPreset{ | ||||
|  | 			Name: body.Name, | ||||
|  | 			Value: newColor, | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		preset.Validate() | ||||
|  | 		err = config.ColorPresetRepository().Save(ctxOf(c), &preset) | ||||
|  | 		if err != nil { | ||||
|  | 			return nil, err | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		return preset, nil | ||||
|  | 	})) | ||||
|  | 
 | ||||
|  | 	r.PUT("/:id", handler(func(c *gin.Context) (interface{}, error) { | ||||
|  | 		var body struct { | ||||
|  | 			Name        *string `json:"name"` | ||||
|  | 			ColorString *string `json:"colorString"` | ||||
|  | 		} | ||||
|  | 		err := parseBody(c, &body) | ||||
|  | 		if err != nil { | ||||
|  | 			return nil, err | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		preset, err := config.ColorPresetRepository().Find(ctxOf(c), intParam(c, "id")) | ||||
|  | 		if err != nil { | ||||
|  | 			return nil, err | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		if body.Name != nil { | ||||
|  | 			preset.Name = *body.Name | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		if body.ColorString != nil { | ||||
|  | 			newColor, err := models.ParseColorValue(*body.ColorString) | ||||
|  | 			if err != nil { | ||||
|  | 				return nil, err | ||||
|  | 			} | ||||
|  | 
 | ||||
|  | 			preset.Value = newColor | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		preset.Validate() | ||||
|  | 		err = config.ColorPresetRepository().Save(ctxOf(c), &preset) | ||||
|  | 		if err != nil { | ||||
|  | 			return nil, err | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		return preset, nil | ||||
|  | 	})) | ||||
|  | } | ||||
| @ -0,0 +1,99 @@ | |||||
|  | package mysql | ||||
|  | 
 | ||||
|  | import ( | ||||
|  | 	"context" | ||||
|  | 	"git.aiterp.net/lucifer/new-server/models" | ||||
|  | 	"github.com/jmoiron/sqlx" | ||||
|  | ) | ||||
|  | 
 | ||||
|  | type presetRecord struct { | ||||
|  | 	ID         int     `db:"id"` | ||||
|  | 	Name       string  `db:"name"` | ||||
|  | 	Hue        float64 `db:"hue"` | ||||
|  | 	Saturation float64 `db:"saturation"` | ||||
|  | 	Kelvin     int     `db:"kelvin"` | ||||
|  | } | ||||
|  | 
 | ||||
|  | type ColorPresetRepo struct { | ||||
|  | 	DBX *sqlx.DB | ||||
|  | } | ||||
|  | 
 | ||||
|  | func (c *ColorPresetRepo) Find(ctx context.Context, id int) (models.ColorPreset, error) { | ||||
|  | 	var record presetRecord | ||||
|  | 	err := c.DBX.GetContext(ctx, &record, "SELECT * FROM color_preset WHERE id = ?", id) | ||||
|  | 	if err != nil { | ||||
|  | 		return models.ColorPreset{}, dbErr(err) | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	return c.fromRecords(record)[0], nil | ||||
|  | } | ||||
|  | 
 | ||||
|  | func (c *ColorPresetRepo) FetchAll(ctx context.Context) ([]models.ColorPreset, error) { | ||||
|  | 	records := make([]presetRecord, 0, 16) | ||||
|  | 	err := c.DBX.SelectContext(ctx, &records, "SELECT * FROM color_preset") | ||||
|  | 	if err != nil { | ||||
|  | 		return nil, dbErr(err) | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	return c.fromRecords(records...), nil | ||||
|  | } | ||||
|  | 
 | ||||
|  | func (c *ColorPresetRepo) Save(ctx context.Context, preset *models.ColorPreset) error { | ||||
|  | 	if preset.ID > 0 { | ||||
|  | 		_, err := c.DBX.ExecContext( | ||||
|  | 			ctx, | ||||
|  | 			"UPDATE color_preset SET name = ?, hue = ?, saturation = ?, kelvin = ? WHERE id = ?", | ||||
|  | 			preset.Name, preset.Value.Hue, preset.Value.Saturation, preset.Value.Kelvin, preset.ID, | ||||
|  | 		) | ||||
|  | 
 | ||||
|  | 		if err != nil { | ||||
|  | 			return dbErr(err) | ||||
|  | 		} | ||||
|  | 	} else { | ||||
|  | 		rs, err := c.DBX.ExecContext( | ||||
|  | 			ctx, | ||||
|  | 			"INSERT INTO color_preset (name, hue, saturation, kelvin) VALUES (?, ?, ?, ?)", | ||||
|  | 			preset.Name, preset.Value.Hue, preset.Value.Saturation, preset.Value.Kelvin, | ||||
|  | 		) | ||||
|  | 
 | ||||
|  | 		if err != nil { | ||||
|  | 			return dbErr(err) | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		id, err := rs.LastInsertId() | ||||
|  | 		if err != nil { | ||||
|  | 			return dbErr(err) | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 		preset.ID = int(id) | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	return nil | ||||
|  | } | ||||
|  | 
 | ||||
|  | func (c *ColorPresetRepo) Delete(ctx context.Context, preset *models.ColorPreset) error { | ||||
|  | 	_, err := c.DBX.ExecContext(ctx, "DELETE FROM color_preset WHERE id = ?", preset.ID) | ||||
|  | 	if err != nil { | ||||
|  | 		return dbErr(err) | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	preset.ID = 0 | ||||
|  | 	return nil | ||||
|  | } | ||||
|  | 
 | ||||
|  | func (c *ColorPresetRepo) fromRecords(records ...presetRecord) []models.ColorPreset { | ||||
|  | 	newList := make([]models.ColorPreset, len(records), len(records)) | ||||
|  | 	for i, record := range records { | ||||
|  | 		newList[i] = models.ColorPreset{ | ||||
|  | 			ID:   record.ID, | ||||
|  | 			Name: record.Name, | ||||
|  | 			Value: models.ColorValue{ | ||||
|  | 				Hue:        record.Hue, | ||||
|  | 				Saturation: record.Saturation, | ||||
|  | 				Kelvin:     record.Kelvin, | ||||
|  | 			}, | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	return newList | ||||
|  | } | ||||
| @ -0,0 +1,26 @@ | |||||
|  | package models | ||||
|  | 
 | ||||
|  | import ( | ||||
|  | 	"context" | ||||
|  | 	"strings" | ||||
|  | ) | ||||
|  | 
 | ||||
|  | type ColorPreset struct { | ||||
|  | 	ID    int        `json:"id"` | ||||
|  | 	Name  string     `json:"name"` | ||||
|  | 	Value ColorValue `json:"value"` | ||||
|  | } | ||||
|  | 
 | ||||
|  | type ColorPresetRepository interface { | ||||
|  | 	Find(ctx context.Context, id int) (ColorPreset, error) | ||||
|  | 	FetchAll(ctx context.Context) ([]ColorPreset, error) | ||||
|  | 	Save(ctx context.Context, preset *ColorPreset) error | ||||
|  | 	Delete(ctx context.Context, preset *ColorPreset) error | ||||
|  | } | ||||
|  | 
 | ||||
|  | func (c *ColorPreset) Validate() { | ||||
|  | 	c.Name = strings.Trim(c.Name, " \t\n") | ||||
|  | 	if len(c.Name) == 0 { | ||||
|  | 		c.Name = c.Value.String() | ||||
|  | 	} | ||||
|  | } | ||||
| @ -0,0 +1,17 @@ | |||||
|  | -- +goose Up | ||||
|  | -- +goose StatementBegin | ||||
|  | CREATE TABLE color_preset | ||||
|  | ( | ||||
|  |     id         INT    NOT NULL AUTO_INCREMENT, | ||||
|  |     hue        DOUBLE NOT NULL, | ||||
|  |     saturation DOUBLE NOT NULL, | ||||
|  |     kelvin     INT    NOT NULL, | ||||
|  | 
 | ||||
|  |     PRIMARY KEY (id) | ||||
|  | ); | ||||
|  | -- +goose StatementEnd | ||||
|  | 
 | ||||
|  | -- +goose Down | ||||
|  | -- +goose StatementBegin | ||||
|  | DROP TABLE color_preset; | ||||
|  | -- +goose StatementEnd | ||||
| @ -0,0 +1,11 @@ | |||||
|  | -- +goose Up | ||||
|  | -- +goose StatementBegin | ||||
|  | ALTER TABLE color_preset | ||||
|  |     ADD COLUMN name VARCHAR(255) NOT NULL DEFAULT 'Unnamed'; | ||||
|  | -- +goose StatementEnd | ||||
|  | 
 | ||||
|  | -- +goose Down | ||||
|  | -- +goose StatementBegin | ||||
|  | ALTER TABLE color_preset | ||||
|  |     DROP COLUMN name; | ||||
|  | -- +goose StatementEnd | ||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue