package repository import ( "context" "database/sql" "encoding/json" "errors" "time" "gitea.d3m0k1d.ru/d3m0k1d/HellreigN/backend/internal/storage" ) type ScriptInterpreter struct { ID int64 `json:"id"` Name string `json:"name"` Label string `json:"label"` Argv []string `json:"argv"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } type ScriptInterpreterCreate struct { Name string `json:"name" binding:"required"` Label string `json:"label" binding:"required"` Argv []string `json:"argv" binding:"required"` } type ScriptInterpreterUpdate struct { Name *string `json:"name"` Label *string `json:"label"` Argv []string `json:"argv"` } type ScriptInterpreterRepo struct { DB *sql.DB } func NewScriptInterpreterRepo(db *sql.DB) *ScriptInterpreterRepo { return &ScriptInterpreterRepo{DB: db} } func (r *ScriptInterpreterRepo) Init(ctx context.Context) error { _, err := r.DB.ExecContext(ctx, storage.CreateScriptInterpretersTable) return err } func (r *ScriptInterpreterRepo) Create( ctx context.Context, in ScriptInterpreterCreate, ) (*ScriptInterpreter, error) { argvJSON, err := json.Marshal(in.Argv) if err != nil { return nil, err } result, err := r.DB.ExecContext(ctx, `INSERT INTO script_interpreters (name, label, argv) VALUES (?, ?, ?)`, in.Name, in.Label, string(argvJSON), ) if err != nil { return nil, err } id, err := result.LastInsertId() if err != nil { return nil, err } return r.GetByID(ctx, id) } func (r *ScriptInterpreterRepo) GetByID(ctx context.Context, id int64) (*ScriptInterpreter, error) { var si ScriptInterpreter var argvJSON string var createdAt, updatedAt string err := r.DB.QueryRowContext( ctx, `SELECT id, name, label, argv, created_at, updated_at FROM script_interpreters WHERE id = ?`, id, ).Scan(&si.ID, &si.Name, &si.Label, &argvJSON, &createdAt, &updatedAt) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, ErrNotFound } return nil, err } if err := json.Unmarshal([]byte(argvJSON), &si.Argv); err != nil { return nil, err } si.CreatedAt, _ = time.Parse(time.RFC3339, createdAt) si.UpdatedAt, _ = time.Parse(time.RFC3339, updatedAt) return &si, nil } func (r *ScriptInterpreterRepo) List(ctx context.Context) ([]ScriptInterpreter, error) { rows, err := r.DB.QueryContext(ctx, `SELECT id, name, label, argv, created_at, updated_at FROM script_interpreters`, ) if err != nil { return nil, err } defer rows.Close() var interpreters []ScriptInterpreter for rows.Next() { var si ScriptInterpreter var argvJSON, createdAt, updatedAt string if err := rows.Scan( &si.ID, &si.Name, &si.Label, &argvJSON, &createdAt, &updatedAt, ); err != nil { return nil, err } if err := json.Unmarshal([]byte(argvJSON), &si.Argv); err != nil { return nil, err } si.CreatedAt, _ = time.Parse(time.RFC3339, createdAt) si.UpdatedAt, _ = time.Parse(time.RFC3339, updatedAt) interpreters = append(interpreters, si) } return interpreters, rows.Err() } func (r *ScriptInterpreterRepo) Update( ctx context.Context, id int64, in ScriptInterpreterUpdate, ) (*ScriptInterpreter, error) { si, err := r.GetByID(ctx, id) if err != nil { return nil, err } set := "" args := make([]interface{}, 0) idx := 1 if in.Name != nil { set += "name = ?" args = append(args, *in.Name) idx++ } if in.Label != nil { if idx > 1 { set += ", " } set += "label = ?" args = append(args, *in.Label) idx++ } if in.Argv != nil { if idx > 1 { set += ", " } argvJSON, err := json.Marshal(in.Argv) if err != nil { return nil, err } set += "argv = ?" args = append(args, string(argvJSON)) idx++ } if idx == 1 { return si, nil } set += ", updated_at = CURRENT_TIMESTAMP" args = append(args, id) _, err = r.DB.ExecContext(ctx, `UPDATE script_interpreters SET `+set+` WHERE id = ?`, args..., ) if err != nil { return nil, err } return r.GetByID(ctx, id) } func (r *ScriptInterpreterRepo) Delete(ctx context.Context, id int64) error { result, err := r.DB.ExecContext(ctx, `DELETE FROM script_interpreters WHERE id = ?`, id, ) if err != nil { return err } affected, err := result.RowsAffected() if err != nil { return err } if affected == 0 { return ErrNotFound } return nil }