DEPO: справочник и событие HANDBOOK — только при изменении состава
Справочник переписывался в DEPO (DELETE + ~90 INSERT + событие HANDBOOK) при каждом запуске bj и раз в 6 часов, даже без изменений — Fancy каждый раз заново сверял участников. Теперь отпечаток состава (без даты) и куда записан хранятся в depo-handbook-written.json: без изменений — один COUNT для проверки и ничего не пишется; не записанное прежде событие HANDBOOK дописывается одно. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
@@ -11,7 +11,9 @@ package lkgateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -20,6 +22,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -660,6 +663,27 @@ func depoWriteHandbookCtx(pctx context.Context, rc *RuntimeConfig) error {
|
||||
log.Printf("depo-events: таблица FTV_M2M_HANDBOOK создана в %s", rc.Snapshot().Fancy.DepoDB())
|
||||
}
|
||||
hbAt, _ := time.Parse(time.RFC3339, hb.At)
|
||||
// Без изменений — базу не трогаем: тот же состав (отпечаток без даты справочника) уже записан в эту базу
|
||||
// и строк в таблице столько же. Событие HANDBOOK, не записанное в прошлый раз, — дописываем одно.
|
||||
sum := depoHandbookSum(hb.Participants, hb.Places)
|
||||
target := rc.Snapshot().Fancy.Server + "/" + rc.Snapshot().Fancy.DepoDB()
|
||||
if st := depoHandbookStateLoad(); st.Sum == sum && st.Target == target {
|
||||
var rows int
|
||||
if db.QueryRowContext(ctx, "SELECT COUNT(*) FROM dbo.FTV_M2M_HANDBOOK").Scan(&rows) == nil && rows == len(hb.Participants)+len(hb.Places) {
|
||||
depoHandbookWritten = time.Now()
|
||||
if st.Event {
|
||||
return nil
|
||||
}
|
||||
if _, err := db.ExecContext(ctx, fsql.QEv10); err != nil {
|
||||
log.Printf("depo-events: справочник без изменений, событие HANDBOOK по-прежнему не записывается: %v — примените скрипты DEPO", err)
|
||||
return nil
|
||||
}
|
||||
st.Event = true
|
||||
depoHandbookStateSave(st)
|
||||
log.Printf("depo-events: справочник без изменений; записано отложенное событие HANDBOOK")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
tx, err := db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -706,9 +730,11 @@ func depoWriteHandbookCtx(pctx context.Context, rc *RuntimeConfig) error {
|
||||
// переносит справочник в юрлица Fancy (FTV_M2M_UPDATE_HANDBOOK). Отдельно от записи справочника: не
|
||||
// записалось (в старой таблице GUID NOT NULL) — справочник всё равно в DEPO, а событие ждёт скриптов.
|
||||
if _, err := db.ExecContext(ctx, fsql.QEv10); err != nil {
|
||||
depoHandbookStateSave(depoHandbookState{Sum: sum, Target: target, Event: false})
|
||||
log.Printf("depo-events: справочник записан в FTV_M2M_HANDBOOK (%d строк), но событие HANDBOOK — нет: %v — примените скрипты DEPO (плашка «Обновление bj требует применить скрипты»)", n, err)
|
||||
return nil
|
||||
}
|
||||
depoHandbookStateSave(depoHandbookState{Sum: sum, Target: target, Event: true})
|
||||
log.Printf("depo-events: справочник участников записан в FTV_M2M_HANDBOOK: %d строк + событие HANDBOOK", n)
|
||||
return nil
|
||||
}
|
||||
@@ -1572,3 +1598,41 @@ func depoProcsMissing(ctx context.Context, db *sql.DB, f FancyMSSQLSettings) str
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// depoHandbookState — что записано в DEPO в последний раз: отпечаток состава справочника, куда (сервер/база)
|
||||
// и записано ли событие HANDBOOK. Без изменений справочник в DEPO не переписывается.
|
||||
type depoHandbookState struct {
|
||||
Sum string `json:"sum"`
|
||||
Target string `json:"target"`
|
||||
Event bool `json:"event"`
|
||||
}
|
||||
|
||||
const depoHandbookStateFile = "/var/lib/bj/.bj/depo-handbook-written.json"
|
||||
|
||||
func depoHandbookStateLoad() depoHandbookState {
|
||||
var st depoHandbookState
|
||||
if b, err := os.ReadFile(depoHandbookStateFile); err == nil {
|
||||
_ = json.Unmarshal(b, &st)
|
||||
}
|
||||
return st
|
||||
}
|
||||
|
||||
func depoHandbookStateSave(st depoHandbookState) {
|
||||
if b, err := json.Marshal(st); err == nil {
|
||||
_ = os.WriteFile(depoHandbookStateFile, b, 0o640)
|
||||
}
|
||||
}
|
||||
|
||||
// depoHandbookSum — отпечаток состава справочника (участники и места расчётов, без даты справочника).
|
||||
func depoHandbookSum(parts, places []HandbookEntry) string {
|
||||
var lines []string
|
||||
for _, e := range parts {
|
||||
lines = append(lines, strings.Join([]string{"P", e.INN, e.Code, e.Kind, e.Name, e.FullName, e.DisplayName, e.EngName}, "|"))
|
||||
}
|
||||
for _, e := range places {
|
||||
lines = append(lines, strings.Join([]string{"S", e.INN, e.Code, e.Name, e.FullName, e.DisplayName, e.EngName}, "|"))
|
||||
}
|
||||
sort.Strings(lines)
|
||||
h := sha256.Sum256([]byte(strings.Join(lines, "\n")))
|
||||
return hex.EncodeToString(h[:12])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user