added the ability to expand the models

This commit is contained in:
2024-04-08 14:17:13 +01:00
parent 274d7d22aa
commit de0b430467
15 changed files with 1086 additions and 197 deletions

View File

@@ -89,6 +89,7 @@ func (x *Handle) handleGets(context *Context) {
return
}
}
context.ShowMessage = false
handleError(&Error{404, "Endpoint not found"}, context)
}
@@ -99,6 +100,7 @@ func (x *Handle) handlePosts(context *Context) {
return
}
}
context.ShowMessage = false
handleError(&Error{404, "Endpoint not found"}, context)
}
@@ -109,6 +111,7 @@ func (x *Handle) handleDeletes(context *Context) {
return
}
}
context.ShowMessage = false
handleError(&Error{404, "Endpoint not found"}, context)
}
@@ -127,12 +130,58 @@ func (c *Context) CheckAuthLevel(authLevel int) bool {
}
type Context struct {
Token *string
User *dbtypes.User
Logger *log.Logger
Db *sql.DB
Writer http.ResponseWriter
R *http.Request
Token *string
User *dbtypes.User
Logger *log.Logger
Db *sql.DB
Writer http.ResponseWriter
R *http.Request
Tx *sql.Tx
ShowMessage bool
}
func (c Context) Prepare(str string) (*sql.Stmt, error) {
if c.Tx == nil {
return c.Db.Prepare(str)
}
return c.Tx.Prepare(str)
}
var TransactionAlreadyStarted = errors.New("Transaction already started")
var TransactionNotStarted = errors.New("Transaction not started")
func (c *Context) StartTx() error {
if c.Tx != nil {
return TransactionAlreadyStarted
}
var err error = nil
c.Tx, err = c.Db.Begin()
return err
}
func (c *Context) CommitTx() error {
if c.Tx == nil {
return TransactionNotStarted
}
err := c.Tx.Commit()
if err != nil {
return err
}
c.Tx = nil
return nil
}
func (c *Context) RollbackTx() error {
if c.Tx == nil {
return TransactionNotStarted
}
err := c.Tx.Rollback()
if err != nil {
return err
}
c.Tx = nil
return nil
}
func (c Context) ToJSON(dat any) *Error {
@@ -200,14 +249,14 @@ func (c *Context) GetModelFromId(id_path string) (*BaseModel, *Error) {
return nil, c.Error500(err)
}
return model, nil
return model, nil
}
func ModelUpdateStatus(c *Context, id string, status int) {
_, err := c.Db.Exec("update models set status=$1 where id=$2;", status, id)
if err != nil {
c.Logger.Error("Failed to update model status", "err", err)
c.Logger.Warn("TODO Maybe handle better")
c.Logger.Error("Failed to update model status", "err", err)
c.Logger.Warn("TODO Maybe handle better")
}
}
@@ -270,6 +319,7 @@ func (x Handle) createContext(handler *Handle, r *http.Request, w http.ResponseW
Db: handler.Db,
Writer: w,
R: r,
ShowMessage: true,
}, nil
}
@@ -278,7 +328,7 @@ func (x Handle) createContext(handler *Handle, r *http.Request, w http.ResponseW
return nil, errors.Join(err, LogoffError)
}
return &Context{token, user, logger, handler.Db, w, r}, nil
return &Context{token, user, logger, handler.Db, w, r, nil, true}, nil
}
func contextlessLogoff(w http.ResponseWriter) {
@@ -457,20 +507,19 @@ func NewHandler(db *sql.DB) *Handle {
if r.Method == "GET" {
x.handleGets(context)
return
}
if r.Method == "POST" {
} else if r.Method == "POST" {
x.handlePosts(context)
return
}
if r.Method == "DELETE" {
} else if r.Method == "DELETE" {
x.handleDeletes(context)
return
}
if r.Method == "OPTIONS" {
return
}
panic("TODO handle method: " + r.Method)
} else if r.Method == "OPTIONS" {
// do nothing
} else {
panic("TODO handle method: " + r.Method)
}
if context.ShowMessage {
context.Logger.Info("Processed", "method", r.Method, "url", r.URL.Path)
}
})
return x

View File

@@ -189,6 +189,7 @@ type JustId struct { Id string }
type Generic struct{ reflect.Type }
var NotFoundError = errors.New("Not found")
var CouldNotInsert = errors.New("Could not insert")
func generateQuery(t reflect.Type) (query string, nargs int) {
nargs = t.NumField()
@@ -200,6 +201,10 @@ func generateQuery(t reflect.Type) (query string, nargs int) {
if !ok {
name = field.Name;
}
if name == "__nil__" {
continue
}
query += strings.ToLower(name) + ","
}
@@ -214,7 +219,13 @@ func GetDbMultitple[T interface{}](c *Context, tablename string, args ...any) ([
query, nargs := generateQuery(t)
rows, err := c.Db.Query(fmt.Sprintf("select %s from %s", query, tablename), args...)
db_query, err := c.Prepare(fmt.Sprintf("select %s from %s", query, tablename))
if err != nil {
return nil, err
}
defer db_query.Close()
rows, err := db_query.Query(args...)
if err != nil {
return nil, err
}
@@ -251,6 +262,43 @@ func mapRow(store interface{}, rows *sql.Rows, nargs int) (err error) {
return nil
}
func InsertReturnId(c *Context, store interface{}, tablename string, returnName string) (id string, err error) {
t := reflect.TypeOf(store).Elem()
query, nargs := generateQuery(t)
query2 := ""
for i := 0; i < nargs; i += 1 {
query2 += fmt.Sprintf("$%d,", i)
}
// Remove last quotation
query2 = query2[0 : len(query2)-1]
val := reflect.ValueOf(store).Elem()
scan_args := make([]interface{}, nargs);
for i := 0; i < nargs; i++ {
valueField := val.Field(i)
scan_args[i] = valueField.Interface()
}
rows, err := c.Db.Query(fmt.Sprintf("insert into %s (%s) values (%s) returning %s", tablename, query, query2, returnName), scan_args...)
if err != nil {
return
}
defer rows.Close()
if !rows.Next() {
return "", CouldNotInsert
}
err = rows.Scan(&id)
if err != nil {
return
}
return
}
func GetDBOnce(c *Context, store interface{}, tablename string, args ...any) error {
t := reflect.TypeOf(store).Elem()