Учёт DEPO: имя базы обязательно, bj базу по серверу не ищет
Имя базы DEPO задаёт клиент — скрипт и подготовка логином администратора работают только с ней. Автопоиск по серверу убран (экран, скрипт, подготовка, проверка подключения, старый экран conn), выбор из нескольких найденных баз — тоже. Вместо поиска — защита от опечатки: скрипт (SQL Server и PostgreSQL), подготовка и проверка подключения сначала убеждаются, что в названной базе есть учётные таблицы OD_FACES и OD_RESTS, иначе останавливаются, ничего не меняя. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
@@ -2,8 +2,8 @@ package lkgateway
|
||||
|
||||
// Подготовка базы учёта DEPO одним действием (06.10.2026). Раньше это были три экрана мастера — логин bj,
|
||||
// таблицы обмена, задание SQL Agent — и три скрипта. Теперь один скрипт делает всё:
|
||||
// - находит базу DEPO на сервере сам (по учётным таблицам OD_FACES и OD_RESTS) — имя базы клиенту знать
|
||||
// не нужно (SQL Server; для PostgreSQL базу назвать придётся: psql не умеет искать по чужим базам);
|
||||
// - работает с базой, которую назвал клиент (сам по серверу не ищет), и сначала проверяет, что в ней есть
|
||||
// учётные таблицы DEPO OD_FACES и OD_RESTS — опечатка в имени не уведёт в чужую базу;
|
||||
// - создаёт логин bj (пароль придумывает bj и запоминает) или обновляет его пароль;
|
||||
// - создаёт таблицы обмена FTV_M2M* и выдаёт логину bj права: чтение учёта, запись в таблицы обмена;
|
||||
// - по галочке «обработку запускает SQL Server Agent» — создаёт задание bj2depo, иначе обработку
|
||||
@@ -50,8 +50,8 @@ func depoGenPassword() string {
|
||||
// sqlStr — строковый литерал T-SQL / PostgreSQL (одинарная кавычка удваивается).
|
||||
func sqlStr(s string) string { return strings.ReplaceAll(s, "'", "''") }
|
||||
|
||||
// depoSetupScript — один скрипт подготовки базы DEPO. db — имя базы (пусто — найти на сервере; только SQL
|
||||
// Server), agentJob — создать задание SQL Server Agent (иначе обработку вызывает bj).
|
||||
// depoSetupScript — один скрипт подготовки базы DEPO. db — имя базы DEPO (задаёт клиент), agentJob — создать
|
||||
// задание SQL Server Agent (иначе обработку вызывает bj).
|
||||
func depoSetupScript(f FancyMSSQLSettings, db, login, pass string, agentJob bool) string {
|
||||
if f.IsPostgres() {
|
||||
return depoSetupScriptPG(f, db, login, pass)
|
||||
@@ -65,13 +65,13 @@ func depoSetupScript(f FancyMSSQLSettings, db, login, pass string, agentJob bool
|
||||
SET NOCOUNT ON;
|
||||
|
||||
-- ===== Проверьте перед запуском ==========================================
|
||||
-- База DEPO: пусто — скрипт найдёт её сам по таблицам OD_FACES и OD_RESTS.
|
||||
-- База DEPO — точное имя базы учёта на этом сервере.
|
||||
DECLARE @db sysname = N'%[3]s';
|
||||
-- Пароль логина bj (%[1]s). Меняете — впишите тот же пароль в bj, шаг «Учёт DEPO».
|
||||
DECLARE @pass nvarchar(128) = N'%[4]s';
|
||||
-- =========================================================================
|
||||
|
||||
-- Что делает: находит базу DEPO, создаёт логин bj и таблицы обмена FTV_M2M*, выдаёт права
|
||||
-- Что делает: проверяет, что @db — база DEPO, создаёт логин bj и таблицы обмена FTV_M2M*, выдаёт права
|
||||
-- (чтение учёта, запись только в таблицы обмена). Обработка обмена: %[2]s.
|
||||
-- Учётные данные DEPO не меняет. Запускать в SSMS или sqlcmd под логином с правами sysadmin.
|
||||
-- Можно запускать повторно. В скрипте пароль логина bj — после выполнения файл удалите.
|
||||
@@ -81,18 +81,19 @@ BEGIN
|
||||
RAISERROR(N'Впишите пароль логина bj в @pass в начале скрипта и запустите снова.', 16, 1);
|
||||
RETURN;
|
||||
END
|
||||
DECLARE @found int;
|
||||
IF @db = N''
|
||||
BEGIN
|
||||
SELECT @found = COUNT(*) FROM sys.databases WHERE state = 0 AND database_id > 4
|
||||
AND OBJECT_ID(QUOTENAME(name) + N'.dbo.OD_FACES') IS NOT NULL AND OBJECT_ID(QUOTENAME(name) + N'.dbo.OD_RESTS') IS NOT NULL;
|
||||
IF @found = 1
|
||||
SELECT @db = name FROM sys.databases WHERE state = 0 AND database_id > 4
|
||||
AND OBJECT_ID(QUOTENAME(name) + N'.dbo.OD_FACES') IS NOT NULL AND OBJECT_ID(QUOTENAME(name) + N'.dbo.OD_RESTS') IS NOT NULL;
|
||||
RAISERROR(N'Впишите имя базы DEPO в @db в начале скрипта и запустите снова.', 16, 1);
|
||||
RETURN;
|
||||
END
|
||||
IF @db = N'' OR DB_ID(@db) IS NULL
|
||||
IF DB_ID(@db) IS NULL
|
||||
BEGIN
|
||||
RAISERROR(N'База DEPO не найдена или на сервере их несколько. Впишите имя базы DEPO в @db в начале скрипта и запустите снова.', 16, 1);
|
||||
RAISERROR(N'Базы %%s на этом сервере нет. Проверьте имя в @db в начале скрипта.', 16, 1, @db);
|
||||
RETURN;
|
||||
END
|
||||
IF OBJECT_ID(QUOTENAME(@db) + N'.dbo.OD_FACES', N'U') IS NULL OR OBJECT_ID(QUOTENAME(@db) + N'.dbo.OD_RESTS', N'U') IS NULL
|
||||
BEGIN
|
||||
RAISERROR(N'В базе %%s нет учётных таблиц DEPO (OD_FACES, OD_RESTS) — это не база DEPO. Проверьте имя в @db.', 16, 1, @db);
|
||||
RETURN;
|
||||
END
|
||||
PRINT N'База DEPO: ' + @db;
|
||||
@@ -162,6 +163,12 @@ END $$;
|
||||
GRANT CONNECT ON DATABASE "%[1]s" TO "%[2]s";
|
||||
|
||||
\c "%[1]s"
|
||||
-- это база DEPO? (учётные таблицы OD_FACES и OD_RESTS) — иначе остановиться, ничего не создавая
|
||||
DO $$ BEGIN
|
||||
IF to_regclass('od_faces') IS NULL OR to_regclass('od_rests') IS NULL THEN
|
||||
RAISE EXCEPTION 'В базе %% нет учётных таблиц DEPO (OD_FACES, OD_RESTS) — проверьте имя базы', current_database();
|
||||
END IF;
|
||||
END $$;
|
||||
`, db, login, sqlStr(pass))
|
||||
for _, s := range depoTablesDDL(true) {
|
||||
b.WriteString(s + ";\n")
|
||||
@@ -182,37 +189,31 @@ func depoSetupFileName(f FancyMSSQLSettings) string {
|
||||
return "bj-depo-setup-mssql.sql"
|
||||
}
|
||||
|
||||
// depoSetupRun — «bj сделает сам»: тот же скрипт выполняется логином администратора (не сохраняется).
|
||||
// Возвращает найденную базу DEPO.
|
||||
func depoSetupRun(ctx context.Context, f FancyMSSQLSettings, db, adminUser, adminPass, login, pass string, agentJob bool) (string, error) {
|
||||
// depoSetupRun — «bj сделает сам»: тот же скрипт выполняется логином администратора (не сохраняется) в базе
|
||||
// db, которую назвал клиент; сначала — проверка, что это база DEPO.
|
||||
func depoSetupRun(ctx context.Context, f FancyMSSQLSettings, db, adminUser, adminPass, login, pass string, agentJob bool) error {
|
||||
adm := f
|
||||
adm.User, adm.Password = strings.TrimSpace(adminUser), adminPass
|
||||
if db == "" {
|
||||
found, err := depoDiscover(ctx, adm)
|
||||
switch {
|
||||
case err != nil:
|
||||
return "", fmt.Errorf("список баз сервера логином %s: %s", adm.User, quikErrorDetail(err))
|
||||
case len(found) == 0:
|
||||
return "", fmt.Errorf("на сервере нет базы учёта DEPO (с таблицами %s), доступной логину %s", strings.Join(depoMarkerTables, " и "), adm.User)
|
||||
case len(found) > 1:
|
||||
return "", fmt.Errorf("на сервере несколько баз DEPO (%s) — укажите нужную в поле «База DEPO»", strings.Join(found, ", "))
|
||||
}
|
||||
db = found[0]
|
||||
if !validDBName(db) {
|
||||
return fmt.Errorf("укажите имя базы DEPO")
|
||||
}
|
||||
if err := depoCheckIsDepo(ctx, adm, db); err != nil {
|
||||
return err
|
||||
}
|
||||
if f.IsPostgres() {
|
||||
return db, depoSetupRunPG(ctx, adm, db, login, pass)
|
||||
return depoSetupRunPG(ctx, adm, db, login, pass)
|
||||
}
|
||||
conn, err := fancyOpen(adm, "")
|
||||
if err != nil {
|
||||
return db, err
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
cctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
|
||||
defer cancel()
|
||||
if _, err := conn.ExecContext(cctx, depoSetupScript(f, db, login, pass, agentJob)); err != nil {
|
||||
return db, fmt.Errorf("подготовка базы %s логином %s: %s%s", db, adm.User, quikErrorDetail(err), depoTablesRightsHint(f, adm.User, err))
|
||||
return fmt.Errorf("подготовка базы %s логином %s: %s%s", db, adm.User, quikErrorDetail(err), depoTablesRightsHint(f, adm.User, err))
|
||||
}
|
||||
return db, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func depoSetupRunPG(ctx context.Context, adm FancyMSSQLSettings, db, login, pass string) error {
|
||||
|
||||
Reference in New Issue
Block a user