certimate/migrations/1742209200_upgrade.go
2025-05-26 21:49:37 +08:00

360 lines
8.6 KiB
Go

package migrations
import (
"encoding/json"
"strings"
"time"
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
)
func init() {
m.Register(func(app core.App) error {
tracer := NewTracer("(v0.3)1742209200")
tracer.Printf("go ...")
// create collection `workflow_logs`
{
jsonData := `{
"createRule": null,
"deleteRule": null,
"fields": [
{
"autogeneratePattern": "[a-z0-9]{15}",
"hidden": false,
"id": "text3208210256",
"max": 15,
"min": 15,
"name": "id",
"pattern": "^[a-z0-9]+$",
"presentable": false,
"primaryKey": true,
"required": true,
"system": true,
"type": "text"
},
{
"cascadeDelete": true,
"collectionId": "tovyif5ax6j62ur",
"hidden": false,
"id": "relation3371272342",
"maxSelect": 1,
"minSelect": 0,
"name": "workflowId",
"presentable": false,
"required": false,
"system": false,
"type": "relation"
},
{
"cascadeDelete": true,
"collectionId": "qjp8lygssgwyqyz",
"hidden": false,
"id": "relation821863227",
"maxSelect": 1,
"minSelect": 0,
"name": "runId",
"presentable": false,
"required": false,
"system": false,
"type": "relation"
},
{
"autogeneratePattern": "",
"hidden": false,
"id": "text157423495",
"max": 0,
"min": 0,
"name": "nodeId",
"pattern": "",
"presentable": false,
"primaryKey": false,
"required": false,
"system": false,
"type": "text"
},
{
"autogeneratePattern": "",
"hidden": false,
"id": "text3227511481",
"max": 0,
"min": 0,
"name": "nodeName",
"pattern": "",
"presentable": false,
"primaryKey": false,
"required": false,
"system": false,
"type": "text"
},
{
"hidden": false,
"id": "number2782324286",
"max": null,
"min": null,
"name": "timestamp",
"onlyInt": false,
"presentable": false,
"required": false,
"system": false,
"type": "number"
},
{
"autogeneratePattern": "",
"hidden": false,
"id": "text2599078931",
"max": 0,
"min": 0,
"name": "level",
"pattern": "",
"presentable": false,
"primaryKey": false,
"required": false,
"system": false,
"type": "text"
},
{
"autogeneratePattern": "",
"hidden": false,
"id": "text3065852031",
"max": 0,
"min": 0,
"name": "message",
"pattern": "",
"presentable": false,
"primaryKey": false,
"required": false,
"system": false,
"type": "text"
},
{
"hidden": false,
"id": "json2918445923",
"maxSize": 0,
"name": "data",
"presentable": false,
"required": false,
"system": false,
"type": "json"
},
{
"hidden": false,
"id": "autodate2990389176",
"name": "created",
"onCreate": true,
"onUpdate": false,
"presentable": false,
"system": false,
"type": "autodate"
}
],
"id": "pbc_1682296116",
"indexes": [
"CREATE INDEX ` + "`" + `idx_IOlpy6XuJ2` + "`" + ` ON ` + "`" + `workflow_logs` + "`" + ` (` + "`" + `workflowId` + "`" + `)",
"CREATE INDEX ` + "`" + `idx_qVlTb2yl7v` + "`" + ` ON ` + "`" + `workflow_logs` + "`" + ` (` + "`" + `runId` + "`" + `)"
],
"listRule": null,
"name": "workflow_logs",
"system": false,
"type": "base",
"updateRule": null,
"viewRule": null
}`
collection := &core.Collection{}
if err := json.Unmarshal([]byte(jsonData), &collection); err != nil {
return err
}
if err := app.Save(collection); err != nil {
return err
}
tracer.Printf("collection '%s' created", collection.Name)
}
// migrate data
{
workflowRuns, err := app.FindAllRecords("workflow_run")
if err != nil {
return err
}
for _, workflowRun := range workflowRuns {
type dWorkflowRunLogRecord struct {
Time string `json:"time"`
Level string `json:"level"`
Content string `json:"content"`
Error string `json:"error"`
}
type dWorkflowRunLog struct {
NodeId string `json:"nodeId"`
NodeName string `json:"nodeName"`
Records []dWorkflowRunLogRecord `json:"records"`
Error string `json:"error"`
}
logs := make([]dWorkflowRunLog, 0)
if err := workflowRun.UnmarshalJSONField("logs", &logs); err != nil {
continue
}
collection, err := app.FindCollectionByNameOrId("workflow_logs")
if err != nil {
return err
}
for _, log := range logs {
for _, logRecord := range log.Records {
record := core.NewRecord(collection)
createdAt, _ := time.Parse(time.RFC3339, logRecord.Time)
record.Set("workflowId", workflowRun.Get("workflowId"))
record.Set("runId", workflowRun.Get("id"))
record.Set("nodeId", log.NodeId)
record.Set("nodeName", log.NodeName)
record.Set("timestamp", createdAt.UnixMilli())
record.Set("level", logRecord.Level)
record.Set("message", strings.TrimSpace(logRecord.Content+" "+logRecord.Error))
record.Set("created", createdAt)
if err := app.Save(record); err != nil {
return err
}
tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name)
}
}
}
}
// update collection `workflow_run`
{
collection, err := app.FindCollectionByNameOrId("workflow_run")
if err != nil {
return err
}
if err := collection.Fields.AddMarshaledJSONAt(6, []byte(`{
"hidden": false,
"id": "json772177811",
"maxSize": 5000000,
"name": "detail",
"presentable": false,
"required": false,
"system": false,
"type": "json"
}`)); err != nil {
return err
}
if err := app.Save(collection); err != nil {
return err
}
tracer.Printf("collection '%s' updated", collection.Name)
}
// migrate data
{
workflowRuns, err := app.FindAllRecords("workflow_run")
if err != nil {
return err
}
workflowOutputs, err := app.FindAllRecords("workflow_output")
if err != nil {
return err
}
type dWorkflowNode struct {
Id string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Config map[string]any `json:"config"`
Inputs []map[string]any `json:"inputs"`
Outputs []map[string]any `json:"outputs"`
Next *dWorkflowNode `json:"next,omitempty"`
Branches []dWorkflowNode `json:"branches,omitempty"`
Validated bool `json:"validated"`
}
for _, workflowRun := range workflowRuns {
node := &dWorkflowNode{}
for _, workflowOutput := range workflowOutputs {
if workflowOutput.GetString("runId") != workflowRun.Get("id") {
continue
}
if err := workflowOutput.UnmarshalJSONField("node", node); err != nil {
continue
}
if node.Type != "apply" {
node = &dWorkflowNode{}
continue
}
}
if node.Id == "" {
workflow, _ := app.FindRecordById("workflow", workflowRun.GetString("workflowId"))
if workflow != nil {
workflowRun.Set("detail", workflow.Get("content"))
} else {
workflowRun.Set("detail", make(map[string]any))
}
} else {
workflow, _ := app.FindRecordById("workflow", workflowRun.GetString("workflowId"))
if workflow != nil {
rootNode := &dWorkflowNode{}
if err := workflow.UnmarshalJSONField("content", rootNode); err != nil {
return err
}
rootNode.Next = node
workflowRun.Set("detail", rootNode)
} else {
rootNode := &dWorkflowNode{
Id: core.GenerateDefaultRandomId(),
Type: "start",
Name: "开始",
Config: map[string]any{
"trigger": "manual",
},
Next: node,
Validated: true,
}
workflowRun.Set("detail", rootNode)
}
}
if err := app.Save(workflowRun); err != nil {
return err
}
tracer.Printf("record #%s in collection '%s' updated", workflowRun.Id, workflowRun.Collection().Name)
}
}
// update collection `workflow_run`
{
collection, err := app.FindCollectionByNameOrId("workflow_run")
if err != nil {
return err
}
collection.Fields.RemoveByName("logs")
if err := app.Save(collection); err != nil {
return err
}
tracer.Printf("collection '%s' updated", collection.Name)
}
tracer.Printf("done")
return nil
}, func(app core.App) error {
return nil
})
}