1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-20 03:17:04 +00:00

reorganization of _examples and add some new examples such as iris+groupcache+mysql+docker

Former-commit-id: ed635ee95de7160cde11eaabc0c1dcb0e460a620
This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-06-07 15:26:06 +03:00
parent 9fdcb4c7fb
commit ed45c77be5
328 changed files with 4262 additions and 41621 deletions

View File

@@ -0,0 +1,74 @@
package service
import (
"context"
"fmt"
"reflect"
"myapp/entity"
"myapp/sql"
)
// CategoryService represents the category entity service.
// Note that the given entity (request) should be already validated
// before service's calls.
type CategoryService struct {
*sql.Service
}
// NewCategoryService returns a new category service to communicate with the database.
func NewCategoryService(db sql.Database) *CategoryService {
return &CategoryService{Service: sql.NewService(db, new(entity.Category))}
}
// Insert stores a category to the database and returns its ID.
func (s *CategoryService) Insert(ctx context.Context, e entity.Category) (int64, error) {
if e.Title == "" || e.ImageURL == "" {
return 0, sql.ErrUnprocessable
}
q := fmt.Sprintf(`INSERT INTO %s (title, position, image_url)
VALUES (?,?,?);`, e.TableName())
res, err := s.DB().Exec(ctx, q, e.Title, e.Position, e.ImageURL)
if err != nil {
return 0, err
}
return res.LastInsertId()
}
// Update updates a category based on its `ID`.
func (s *CategoryService) Update(ctx context.Context, e entity.Category) (int, error) {
if e.ID == 0 || e.Title == "" || e.ImageURL == "" {
return 0, sql.ErrUnprocessable
}
q := fmt.Sprintf(`UPDATE %s
SET
title = ?,
position = ?,
image_url = ?
WHERE %s = ?;`, e.TableName(), e.PrimaryKey())
res, err := s.DB().Exec(ctx, q, e.Title, e.Position, e.ImageURL, e.ID)
if err != nil {
return 0, err
}
n := sql.GetAffectedRows(res)
return n, nil
}
// The updatable fields, separately from that we create for any possible future necessities.
var categoryUpdateSchema = map[string]reflect.Kind{
"title": reflect.String,
"image_url": reflect.String,
"position": reflect.Int,
}
// PartialUpdate accepts a key-value map to
// update the record based on the given "id".
func (s *CategoryService) PartialUpdate(ctx context.Context, id int64, attrs map[string]interface{}) (int, error) {
return s.Service.PartialUpdate(ctx, id, categoryUpdateSchema, attrs)
}

View File

@@ -0,0 +1,42 @@
package service
import (
"context"
"testing"
"myapp/entity"
"myapp/sql"
"github.com/DATA-DOG/go-sqlmock"
)
func TestCategoryServiceInsert(t *testing.T) {
conn, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
if err != nil {
t.Fatal(err)
}
defer conn.Close()
db := &sql.MySQL{Conn: conn}
service := NewCategoryService(db)
newCategory := entity.Category{
Title: "computer-internet",
Position: 2,
ImageURL: "https://animage",
}
mock.ExpectExec("INSERT INTO categories (title, position, image_url) VALUES (?,?,?);").
WithArgs(newCategory.Title, newCategory.Position, newCategory.ImageURL).WillReturnResult(sqlmock.NewResult(1, 1))
id, err := service.Insert(context.TODO(), newCategory)
if err != nil {
t.Fatal(err)
}
if id != 1 {
t.Fatalf("expected ID to be 1 as this is the first entry")
}
if err = mock.ExpectationsWereMet(); err != nil {
t.Fatal(err)
}
}

View File

@@ -0,0 +1,110 @@
package service
import (
"context"
"fmt"
"reflect"
"strings"
"myapp/entity"
"myapp/sql"
)
// ProductService represents the product entity service.
// Note that the given entity (request) should be already validated
// before service's calls.
type ProductService struct {
*sql.Service
rec sql.Record
}
// NewProductService returns a new product service to communicate with the database.
func NewProductService(db sql.Database) *ProductService {
return &ProductService{Service: sql.NewService(db, new(entity.Product))}
}
// Insert stores a product to the database and returns its ID.
func (s *ProductService) Insert(ctx context.Context, e entity.Product) (int64, error) {
if !e.ValidateInsert() {
return 0, sql.ErrUnprocessable
}
q := fmt.Sprintf(`INSERT INTO %s (category_id, title, image_url, price, description)
VALUES (?,?,?,?,?);`, e.TableName())
res, err := s.DB().Exec(ctx, q, e.CategoryID, e.Title, e.ImageURL, e.Price, e.Description)
if err != nil {
return 0, err
}
return res.LastInsertId()
}
// BatchInsert inserts one or more products at once and returns the total length created.
func (s *ProductService) BatchInsert(ctx context.Context, products []entity.Product) (int, error) {
if len(products) == 0 {
return 0, nil
}
var (
valuesLines []string
args []interface{}
)
for _, p := range products {
if !p.ValidateInsert() {
// all products should be "valid", we don't skip, we cancel.
return 0, sql.ErrUnprocessable
}
valuesLines = append(valuesLines, "(?,?,?,?,?)")
args = append(args, []interface{}{p.CategoryID, p.Title, p.ImageURL, p.Price, p.Description}...)
}
q := fmt.Sprintf("INSERT INTO %s (category_id, title, image_url, price, description) VALUES %s;",
s.RecordInfo().TableName(),
strings.Join(valuesLines, ", "))
res, err := s.DB().Exec(ctx, q, args...)
if err != nil {
return 0, err
}
n := sql.GetAffectedRows(res)
return n, nil
}
// Update updates a product based on its `ID` from the database
// and returns the affected numbrer (0 when nothing changed otherwise 1).
func (s *ProductService) Update(ctx context.Context, e entity.Product) (int, error) {
q := fmt.Sprintf(`UPDATE %s
SET
category_id = ?,
title = ?,
image_url = ?,
price = ?,
description = ?
WHERE %s = ?;`, e.TableName(), e.PrimaryKey())
res, err := s.DB().Exec(ctx, q, e.CategoryID, e.Title, e.ImageURL, e.Price, e.Description, e.ID)
if err != nil {
return 0, err
}
n := sql.GetAffectedRows(res)
return n, nil
}
var productUpdateSchema = map[string]reflect.Kind{
"category_id": reflect.Int,
"title": reflect.String,
"image_url": reflect.String,
"price": reflect.Float32,
"description": reflect.String,
}
// PartialUpdate accepts a key-value map to
// update the record based on the given "id".
func (s *ProductService) PartialUpdate(ctx context.Context, id int64, attrs map[string]interface{}) (int, error) {
return s.Service.PartialUpdate(ctx, id, productUpdateSchema, attrs)
}