controllers

package
v0.0.0-...-4584b3d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2024 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const ControllerTemplate = `` /* 1186-byte string literal not displayed */
View Source
const ControllersRegisterTemplate = `// generated code - do not edit
package controllers

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"time"

	"{{PkgPathRoot}}/orm"

	"github.com/gin-gonic/gin"

	"github.com/gorilla/websocket"
)

// genQuery return the name of the column
func genQuery(columnName string) string {
	return fmt.Sprintf("%s = ?", columnName)
}

// A GenericError is the default error message that is generated.
// For certain status codes there are more appropriate error structures.
//
// swagger:response genericError
type GenericError struct {
	// in: body
	Body struct {
		Code    int32  ` + "`" + `json:"code"` + "`" + `
		Message string ` + "`" + `json:"message"` + "`" + `
	} ` + "`" + `json:"body"` + "`" + `
}

// A ValidationError is an that is generated for validation failures.
// It has the same fields as a generic error but adds a Field property.
//
// swagger:response validationError
type ValidationError struct {
	// in: body
	Body struct {
		Code    int32  ` + "`" + `json:"code"` + "`" + `
		Message string ` + "`" + `json:"message"` + "`" + `
		Field   string ` + "`" + `json:"field"` + "`" + `
	} ` + "`" + `json:"body"` + "`" + `
}

// registerControllers register controllers
func registerControllers(r *gin.Engine) {
	v1 := r.Group("/api/{{PkgPathRoot}}")
	{ // insertion point for registrations{{` + string(rune(ControllersDeclaration)) + `}}
		v1.GET("/v1/commitfrombacknb", GetController().GetLastCommitFromBackNb)
		v1.GET("/v1/pushfromfrontnb", GetController().GetLastPushFromFrontNb)

		v1.GET("/v1/ws/stage", GetController().onWebSocketRequestForBackRepoContent)

		v1.GET("/v1/stacks", GetController().stacks)
	}
}

func (controller *Controller) stacks(c *gin.Context) {

	var res []string

	for k := range controller.Map_BackRepos {
		res = append(res, k)
	}

	c.JSON(http.StatusOK, res)
}

// onWebSocketRequestForBackRepoContent is a function that is started each time
// a web socket request is received
//
// 1. upgrade the incomming web connection to a web socket
// 1. it subscribe to the backend commit number broadcaster
// 1. it stays live and pool for incomming backend commit number broadcast and forward
// them on the web socket connection
func (controller *Controller) onWebSocketRequestForBackRepoContent(c *gin.Context) {

	// log.Println("Stack {{PkgPathRoot}}, onWebSocketRequestForBackRepoContent")

	// Upgrader specifies parameters for upgrading an HTTP connection to a
	// WebSocket connection.
	var upgrader = websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			origin := r.Header.Get("Origin")
			return origin == "http://localhost:8080" || origin == "http://localhost:4200"
		},
	}

	wsConnection, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer wsConnection.Close()

	// Create a context that is canceled when the connection is closed
	ctx, cancel := context.WithCancel(c.Request.Context())
	defer cancel()

	values := c.Request.URL.Query()
	stackPath := ""
	if len(values) == 1 {
		value := values["GONG__StackPath"]
		if len(value) == 1 {
			stackPath = value[0]
			// log.Println("GetLastCommitFromBackNb", "GONG__StackPath", stackPath)
		}
	}

	log.Printf("Stack {{PkgPathRoot}}: stack path: '%s', new ws index %d",
		stackPath, controller.listenerIndex,
	)
	controller.listenerIndex++

	backRepo := controller.Map_BackRepos[stackPath]
	if backRepo == nil {
		log.Panic("Stack {{PkgPathRoot}}, Unkown stack", stackPath)
	}
	updateCommitBackRepoNbChannel := backRepo.SubscribeToCommitNb(ctx)

	// Start a goroutine to read from the WebSocket to detect disconnection
	go func() {
		for {
			// ReadMessage is used to detect client disconnection
			_, _, err := wsConnection.ReadMessage()
			if err != nil {
				log.Println("{{PkgPathRoot}}", stackPath, "WS client disconnected:", err)
				cancel() // Cancel the context
				return
			}
		}
	}()

	backRepoData := new(orm.BackRepoData)
	orm.CopyBackRepoToBackRepoData(backRepo, backRepoData)

	err = wsConnection.WriteJSON(backRepoData)
	if err != nil {
		log.Println("{{PkgPathRoot}}:\n",
			"client no longer receiver web socket message, assuming it is no longer alive, closing websocket handler")
		fmt.Println(err)
		return
	} else {
		log.Println(time.Now().Format(time.RFC3339Nano), "{{PkgPathRoot}}: 1st sent backRepoData of stack:", stackPath)
	}
	for {
		select {
		case <-ctx.Done():
			// Context canceled, exit the loop
			return
		default:
			for nbCommitBackRepo := range updateCommitBackRepoNbChannel {
				_ = nbCommitBackRepo

				backRepoData := new(orm.BackRepoData)
				orm.CopyBackRepoToBackRepoData(backRepo, backRepoData)

				// Set write deadline to prevent blocking indefinitely
				wsConnection.SetWriteDeadline(time.Now().Add(10 * time.Second))

				// Send backRepo data
				err = wsConnection.WriteJSON(backRepoData)
				if err != nil {
					log.Println("{{PkgPathRoot}}:\n", stackPath,
						"client no longer receiver web socket message,closing websocket handler")
					fmt.Println(err)
					cancel() // Cancel the context
					return
				} else {
					log.Println(time.Now().Format(time.RFC3339Nano), "{{PkgPathRoot}}: sent backRepoData of stack:", stackPath)
				}
			}
		}
	}
}

// swagger:route GET /commitfrombacknb backrepo GetLastCommitFromBackNb
func (controller *Controller) GetLastCommitFromBackNb(c *gin.Context) {
	values := c.Request.URL.Query()
	stackPath := ""
	if len(values) == 1 {
		value := values["GONG__StackPath"]
		if len(value) == 1 {
			stackPath = value[0]
			// log.Println("GetLastCommitFromBackNb", "GONG__StackPath", stackPath)
		}
	}
	backRepo := controller.Map_BackRepos[stackPath]
	if backRepo == nil {
		log.Panic("Stack {{PkgPathRoot}}/models, Unkown stack", stackPath)
	}
	res := backRepo.GetLastCommitFromBackNb()

	c.JSON(http.StatusOK, res)
}

// swagger:route GET /pushfromfrontnb backrepo GetLastPushFromFrontNb
func (controller *Controller) GetLastPushFromFrontNb(c *gin.Context) {
	values := c.Request.URL.Query()
	stackPath := ""
	if len(values) == 1 {
		value := values["GONG__StackPath"]
		if len(value) == 1 {
			stackPath = value[0]
			// log.Println("GetLastPushFromFrontNb", "GONG__StackPath", stackPath)
		}
	}
	backRepo := controller.Map_BackRepos[stackPath]
	if backRepo == nil {
		log.Panic("Stack {{PkgPathRoot}}/models, Unkown stack", stackPath)
	}
	res := backRepo.GetLastPushFromFrontNb()

	c.JSON(http.StatusOK, res)
}
`

Variables

View Source
var ControllerFileFieldFieldSubTemplateCode map[ControllerFilPerStructSubTemplate]string = map[ControllerFilPerStructSubTemplate]string{

	ControllerFileFieldSubTmplGetsBasicFieldBool: `
		{{structname}}.{{FieldName}} = {{structname}}.{{FieldName}}_Data.Bool
`,

	ControllerFileFieldSubTmplPostBasicFieldBool: `
	{{structname}}DB.{{FieldName}}_Data.Bool = input.{{FieldName}}
	{{structname}}DB.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetBasicFieldBool: `
	{{structname}}.{{FieldName}} = {{structname}}.{{FieldName}}_Data.Bool
`,

	ControllerFileFieldSubTmplUpdateBasicFieldBool: `
	input.{{FieldName}}_Data.Bool = input.{{FieldName}}
	input.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetsTimeField: `
		if {{structname}}.{{FieldName}}_Data.Valid {
			{{structname}}.{{FieldName}} = {{structname}}.{{FieldName}}_Data.Time
		}
`,

	ControllerFileFieldSubTmplPostTimeField: `
	{{structname}}DB.{{FieldName}}_Data.Time = input.{{FieldName}}
	{{structname}}DB.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetTimeField: `
	if {{structname}}.{{FieldName}}_Data.Valid {
		{{structname}}.{{FieldName}} = {{structname}}.{{FieldName}}_Data.Time
	}
`,

	ControllerFileFieldSubTmplUpdateTimeField: `
	input.{{FieldName}}_Data.Time = input.{{FieldName}}
	input.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetsBasicFieldInt: `
		if {{structname}}.{{FieldName}}_Data.Valid {
			{{structname}}.{{FieldName}} = {{FieldType}}({{structname}}.{{FieldName}}_Data.Int64)
		}
`,

	ControllerFileFieldSubTmplPostBasicFieldInt: `
	{{structname}}DB.{{FieldName}}_Data.Int64 = int64(input.{{FieldName}})
	{{structname}}DB.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetBasicFieldInt: `
	if {{structname}}.{{FieldName}}_Data.Valid {
		{{structname}}.{{FieldName}} = {{FieldType}}({{structname}}.{{FieldName}}_Data.Int64)
	}
`,

	ControllerFileFieldSubTmplUpdateBasicFieldInt: `
	input.{{FieldName}}_Data.Int64 = int64(input.{{FieldName}})
	input.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetsBasicFieldFloat64: `
		if {{structname}}.{{FieldName}}_Data.Valid {
			{{structname}}.{{FieldName}} = {{structname}}.{{FieldName}}_Data.Float64
		}
`,

	ControllerFileFieldSubTmplPostBasicFieldFloat64: `
	{{structname}}DB.{{FieldName}}_Data.Float64 = input.{{FieldName}}
	{{structname}}DB.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetBasicFieldFloat64: `
	if {{structname}}.{{FieldName}}_Data.Valid {
		{{structname}}.{{FieldName}} = {{structname}}.{{FieldName}}_Data.Float64
	}
`,

	ControllerFileFieldSubTmplUpdateBasicFieldFloat64: `
	input.{{FieldName}}_Data.Float64 = input.{{FieldName}}
	input.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetsBasicFieldString: `
		if {{structname}}.{{FieldName}}_Data.Valid {
			{{structname}}.{{FieldName}} = {{structname}}.{{FieldName}}_Data.String
		}
`,

	ControllerFileFieldSubTmplPostBasicFieldString: `
	{{structname}}DB.{{FieldName}}_Data.String = input.{{FieldName}}
	{{structname}}DB.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetBasicFieldString: `
	if {{structname}}.{{FieldName}}_Data.Valid {
		{{structname}}.{{FieldName}} = {{structname}}.{{FieldName}}_Data.String
	}
`,

	ControllerFileFieldSubTmplUpdateBasicFieldString: `
	input.{{FieldName}}_Data.String = input.{{FieldName}}
	input.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetsBasicFieldStringEnum: `
		if {{structname}}.{{FieldName}}_Data.Valid {
			{{structname}}.{{FieldName}} = models.{{EnumType}}({{structname}}.{{FieldName}}_Data.String)
		}
`,

	ControllerFileFieldSubTmplPostBasicFieldStringEnum: `
	{{structname}}DB.{{FieldName}}_Data.String = string(input.{{FieldName}})
	{{structname}}DB.{{FieldName}}_Data.Valid = true
`,

	ControllerFileFieldSubTmplGetBasicFieldStringEnum: `
	if {{structname}}.{{FieldName}}_Data.Valid {
		{{structname}}.{{FieldName}} = models.{{EnumType}}({{structname}}.{{FieldName}}_Data.String)
	}
`,

	ControllerFileFieldSubTmplUpdateBasicFieldStringEnum: `
	input.{{FieldName}}_Data.String = string(input.{{FieldName}})
	input.{{FieldName}}_Data.Valid = true
`,
}
View Source
var ControllersRegistrationsSubTemplate map[string]string = map[string]string{

	string(rune(ControllersDeclaration)): `
		v1.GET("/v1/{{structname}}s", GetController().Get{{Structname}}s)
		v1.GET("/v1/{{structname}}s/:id", GetController().Get{{Structname}})
		v1.POST("/v1/{{structname}}s", GetController().Post{{Structname}})
		v1.PATCH("/v1/{{structname}}s/:id", GetController().Update{{Structname}})
		v1.PUT("/v1/{{structname}}s/:id", GetController().Update{{Structname}})
		v1.DELETE("/v1/{{structname}}s/:id", GetController().Delete{{Structname}})
`,
}

Functions

func MultiCodeGeneratorControllers

func MultiCodeGeneratorControllers(
	modelPkg *models.ModelPkg,
	pkgName string,
	pkgGoPath string,
	dirPath string)

MultiCodeGeneratorControllers parses mdlPkg and generates the code for the back repository code

Types

type ControllerFilPerStructSubTemplate

type ControllerFilPerStructSubTemplate int

Sub Templates

const (
	ControllerFileFieldSubTmplGetsBasicFieldBool ControllerFilPerStructSubTemplate = iota
	ControllerFileFieldSubTmplPostBasicFieldBool
	ControllerFileFieldSubTmplGetBasicFieldBool
	ControllerFileFieldSubTmplUpdateBasicFieldBool

	ControllerFileFieldSubTmplGetsBasicFieldInt
	ControllerFileFieldSubTmplPostBasicFieldInt
	ControllerFileFieldSubTmplGetBasicFieldInt
	ControllerFileFieldSubTmplUpdateBasicFieldInt

	ControllerFileFieldSubTmplGetsBasicFieldFloat64
	ControllerFileFieldSubTmplPostBasicFieldFloat64
	ControllerFileFieldSubTmplGetBasicFieldFloat64
	ControllerFileFieldSubTmplUpdateBasicFieldFloat64

	ControllerFileFieldSubTmplGetsBasicFieldString
	ControllerFileFieldSubTmplPostBasicFieldString
	ControllerFileFieldSubTmplGetBasicFieldString
	ControllerFileFieldSubTmplUpdateBasicFieldString

	ControllerFileFieldSubTmplGetsTimeField
	ControllerFileFieldSubTmplPostTimeField
	ControllerFileFieldSubTmplGetTimeField
	ControllerFileFieldSubTmplUpdateTimeField

	ControllerFileFieldSubTmplGetsBasicFieldStringEnum
	ControllerFileFieldSubTmplPostBasicFieldStringEnum
	ControllerFileFieldSubTmplGetBasicFieldStringEnum
	ControllerFileFieldSubTmplUpdateBasicFieldStringEnum
)

type ControllerFileInsertionPoint

type ControllerFileInsertionPoint int

insertion points

const (
	ControllerFileGetsInsertion ControllerFileInsertionPoint = iota
	ControllerFilePostInsertion
	ControllerFileGetInsertion
	ControllerFileUpdateInsertion
	ControllerFileNbInsertionPoints
)

type ControllersRegistrationsSubTemplateInsertions

type ControllersRegistrationsSubTemplateInsertions int
const (
	ControllersDeclaration ControllersRegistrationsSubTemplateInsertions = iota
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL