2024-05-02 19:30:25 +00:00
|
|
|
package models
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2024-05-22 16:51:46 +00:00
|
|
|
chatbotRuleColumns = "id, chatbot_id, parameters"
|
2024-05-02 19:30:25 +00:00
|
|
|
chatbotRuleTable = "chatbot_rule"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ChatbotRule struct {
|
2024-05-22 16:51:46 +00:00
|
|
|
ID *int64 `json:"id"`
|
|
|
|
ChatbotID *int64 `json:"chatbot_id"`
|
|
|
|
Parameters *string `json:"parameters"`
|
2024-05-02 19:30:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ChatbotRule) values() []any {
|
2024-05-22 16:51:46 +00:00
|
|
|
return []any{c.ID, c.ChatbotID, c.Parameters}
|
2024-05-02 19:30:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ChatbotRule) valuesNoID() []any {
|
|
|
|
return c.values()[1:]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ChatbotRule) valuesEndID() []any {
|
|
|
|
vals := c.values()
|
|
|
|
return append(vals[1:], vals[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
type sqlChatbotRule struct {
|
2024-05-22 16:51:46 +00:00
|
|
|
id sql.NullInt64
|
|
|
|
chatbotID sql.NullInt64
|
|
|
|
parameters sql.NullString
|
2024-05-02 19:30:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (sc *sqlChatbotRule) scan(r Row) error {
|
2024-05-22 16:51:46 +00:00
|
|
|
return r.Scan(&sc.id, &sc.chatbotID, &sc.parameters)
|
2024-05-02 19:30:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (sc sqlChatbotRule) toChatbotRule() *ChatbotRule {
|
|
|
|
var c ChatbotRule
|
|
|
|
c.ID = toInt64(sc.id)
|
|
|
|
c.ChatbotID = toInt64(sc.chatbotID)
|
2024-05-22 16:51:46 +00:00
|
|
|
c.Parameters = toString(sc.parameters)
|
2024-05-02 19:30:25 +00:00
|
|
|
|
|
|
|
return &c
|
|
|
|
}
|
|
|
|
|
|
|
|
type ChatbotRuleService interface {
|
|
|
|
AutoMigrate() error
|
2024-05-22 16:51:46 +00:00
|
|
|
ByChatbotID(cid int64) ([]ChatbotRule, error)
|
2024-05-02 19:30:25 +00:00
|
|
|
Create(c *ChatbotRule) (int64, error)
|
|
|
|
Delete(c *ChatbotRule) error
|
|
|
|
DestructiveReset() error
|
|
|
|
Update(c *ChatbotRule) error
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewChatbotRuleService(db *sql.DB) ChatbotRuleService {
|
|
|
|
return &chatbotRuleService{
|
|
|
|
Database: db,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ ChatbotRuleService = &chatbotRuleService{}
|
|
|
|
|
|
|
|
type chatbotRuleService struct {
|
|
|
|
Database *sql.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cs *chatbotRuleService) AutoMigrate() error {
|
|
|
|
err := cs.createChatbotRuleTable()
|
|
|
|
if err != nil {
|
|
|
|
return pkgErr(fmt.Sprintf("error creating %s table", chatbotRuleTable), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cs *chatbotRuleService) createChatbotRuleTable() error {
|
|
|
|
createQ := fmt.Sprintf(`
|
|
|
|
CREATE TABLE IF NOT EXISTS "%s" (
|
|
|
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
|
|
chatbot_id INTEGER NOT NULL,
|
2024-05-22 16:51:46 +00:00
|
|
|
parameters TEXT NOT NULL,
|
2024-05-02 19:30:25 +00:00
|
|
|
FOREIGN KEY (chatbot_id) REFERENCES "%s" (id)
|
|
|
|
)
|
|
|
|
`, chatbotRuleTable, chatbotTable)
|
|
|
|
|
|
|
|
_, err := cs.Database.Exec(createQ)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error executing create query: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-05-22 16:51:46 +00:00
|
|
|
func (cs *chatbotRuleService) ByChatbotID(cid int64) ([]ChatbotRule, error) {
|
|
|
|
selectQ := fmt.Sprintf(`
|
|
|
|
SELECT %s
|
|
|
|
FROM "%s"
|
|
|
|
WHERE chatbot_id=?
|
|
|
|
`, chatbotRuleColumns, chatbotRuleTable)
|
|
|
|
|
|
|
|
rows, err := cs.Database.Query(selectQ, cid)
|
|
|
|
if err != nil {
|
|
|
|
return nil, pkgErr("error executing select query", err)
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
rules := []ChatbotRule{}
|
|
|
|
for rows.Next() {
|
|
|
|
scr := &sqlChatbotRule{}
|
|
|
|
|
|
|
|
err = scr.scan(rows)
|
|
|
|
if err != nil {
|
|
|
|
return nil, pkgErr("error scanning row", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
rules = append(rules, *scr.toChatbotRule())
|
|
|
|
}
|
|
|
|
err = rows.Err()
|
|
|
|
if err != nil && err != sql.ErrNoRows {
|
|
|
|
return nil, pkgErr("error iterating over rows", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return rules, nil
|
|
|
|
}
|
|
|
|
|
2024-05-02 19:30:25 +00:00
|
|
|
func (cs *chatbotRuleService) Create(c *ChatbotRule) (int64, error) {
|
|
|
|
err := runChatbotRuleValFuncs(
|
|
|
|
c,
|
2024-05-22 16:51:46 +00:00
|
|
|
chatbotRuleRequireParameters,
|
2024-05-02 19:30:25 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return -1, pkgErr("invalid chat rule", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
columns := columnsNoID(chatbotRuleColumns)
|
|
|
|
insertQ := fmt.Sprintf(`
|
|
|
|
INSERT INTO "%s" (%s)
|
|
|
|
VALUES (%s)
|
|
|
|
RETURNING id
|
|
|
|
`, chatbotRuleTable, columns, values(columns))
|
|
|
|
|
|
|
|
var id int64
|
|
|
|
row := cs.Database.QueryRow(insertQ, c.valuesNoID()...)
|
|
|
|
err = row.Scan(&id)
|
|
|
|
if err != nil {
|
|
|
|
return -1, pkgErr("error executing insert query", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return id, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cs *chatbotRuleService) Delete(c *ChatbotRule) error {
|
|
|
|
err := runChatbotRuleValFuncs(
|
|
|
|
c,
|
|
|
|
chatbotRuleRequireID,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return pkgErr("invalid chat rule", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
deleteQ := fmt.Sprintf(`
|
|
|
|
DELETE FROM "%s"
|
|
|
|
WHERE id=?
|
|
|
|
`, chatbotRuleTable)
|
|
|
|
|
|
|
|
_, err = cs.Database.Exec(deleteQ, c.ID)
|
|
|
|
if err != nil {
|
|
|
|
return pkgErr("error executing delete query", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cs *chatbotRuleService) DestructiveReset() error {
|
|
|
|
err := cs.dropChatbotRuleTable()
|
|
|
|
if err != nil {
|
|
|
|
return pkgErr(fmt.Sprintf("error dropping %s table", chatbotRuleTable), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cs *chatbotRuleService) dropChatbotRuleTable() error {
|
|
|
|
dropQ := fmt.Sprintf(`
|
|
|
|
DROP TABLE IF EXISTS "%s"
|
|
|
|
`, chatbotRuleTable)
|
|
|
|
|
|
|
|
_, err := cs.Database.Exec(dropQ)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error executing drop query: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cs *chatbotRuleService) Update(c *ChatbotRule) error {
|
|
|
|
err := runChatbotRuleValFuncs(
|
|
|
|
c,
|
|
|
|
chatbotRuleRequireID,
|
2024-05-22 16:51:46 +00:00
|
|
|
chatbotRuleRequireParameters,
|
2024-05-02 19:30:25 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return pkgErr("invalid chat rule", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
columns := columnsNoID(chatbotRuleColumns)
|
|
|
|
updateQ := fmt.Sprintf(`
|
|
|
|
UPDATE "%s"
|
|
|
|
SET %s
|
|
|
|
WHERE id=?
|
|
|
|
`, chatbotRuleTable, set(columns))
|
|
|
|
|
|
|
|
_, err = cs.Database.Exec(updateQ, c.valuesEndID()...)
|
|
|
|
if err != nil {
|
|
|
|
return pkgErr("error executing update query", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type chatbotRuleValFunc func(*ChatbotRule) error
|
|
|
|
|
|
|
|
func runChatbotRuleValFuncs(c *ChatbotRule, fns ...chatbotRuleValFunc) error {
|
|
|
|
if c == nil {
|
|
|
|
return fmt.Errorf("chat rule is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, fn := range fns {
|
|
|
|
err := fn(c)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func chatbotRuleRequireID(c *ChatbotRule) error {
|
|
|
|
if c.ID == nil || *c.ID < 1 {
|
|
|
|
return ErrChatbotRuleInvalidID
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-05-22 16:51:46 +00:00
|
|
|
func chatbotRuleRequireParameters(c *ChatbotRule) error {
|
|
|
|
if c.Parameters == nil || *c.Parameters == "" {
|
|
|
|
return ErrChatbotRuleInvalidParameters
|
2024-05-02 19:30:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|