- шаги PocketBase переехали из файла в пакет internal/adapter/repo/pocketbase/migrations, файл на шаг с именем зарегистрированного шага; туда же имена коллекций, срок сессии — в provider.go - ключ migrations в docs/.docs.json наведён на этот каталог: прежнее значение указывало на несуществующий migrations/, и шаг гейта проходил зелёным при всякой правке схемы - app.go подключает пакет шагов явным пустым импортом: пропавшая ссылка на константы унесла бы регистрацию, и хранилище поднялось бы без коллекций
59 lines
3.3 KiB
Go
59 lines
3.3 KiB
Go
// Package pocketbase — хранилище задач и файлов поверх встроенной PocketBase.
|
|
//
|
|
// Приложение поднимается библиотекой, а не её набором команд: разбор флагов и
|
|
// мягкая остановка остаются нашими, а ключ `-c config.toml` — объявленный
|
|
// контракт запуска.
|
|
package pocketbase
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
pb "github.com/pocketbase/pocketbase"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
|
|
// Шаги схемы регистрируются загрузкой своего пакета, а накатывает их
|
|
// `RunAllMigrations` ниже. Импорт здесь пустой и явный, хотя соседние файлы
|
|
// пакета и так берут оттуда имена коллекций: день, когда имена перестанут
|
|
// читаться отсюда, унёс бы вместе с последней ссылкой и регистрацию — список
|
|
// шагов остался бы пустым, `RunAllMigrations` вернул бы `nil`, и приложение
|
|
// поднялось бы здоровым, но без коллекций. Отказ вылез бы не на старте, а на
|
|
// первом приёме записи.
|
|
_ "git.vakhrushev.me/av/transcriber/internal/adapter/repo/pocketbase/migrations"
|
|
)
|
|
|
|
// New создаёт приложение хранилища на заданном каталоге данных и приводит его в
|
|
// рабочее состояние: открывает базу, читает настройки и накатывает непринятые
|
|
// шаги схемы.
|
|
//
|
|
// Схема накатывается **здесь**, а не оставляется серверу, хотя тот и гоняет
|
|
// непринятые шаги сам. Причина в порядке: воркеры стартуют раньше сервера, и на
|
|
// чистом каталоге их первые опросы приходились бы на несуществующую таблицу —
|
|
// отказ в журнале и в счётчике на каждую секунду до конца накатки.
|
|
func New(dataDir string) (*pb.PocketBase, error) {
|
|
app := pb.NewWithConfig(pb.Config{
|
|
DefaultDataDir: dataDir,
|
|
HideStartBanner: true,
|
|
})
|
|
|
|
if err := app.Bootstrap(); err != nil {
|
|
return nil, fmt.Errorf("failed to bootstrap storage: %w", err)
|
|
}
|
|
|
|
if err := app.RunAllMigrations(); err != nil {
|
|
return nil, fmt.Errorf("failed to apply storage schema: %w", err)
|
|
}
|
|
|
|
return app, nil
|
|
}
|
|
|
|
// MustFindCollection достаёт коллекцию по имени. Отсутствие коллекции здесь —
|
|
// не отказ окружения, а несделанный шаг схемы: сервис до этой точки не доходит,
|
|
// потому что Serve накатывает схему прежде, чем поднять сервер.
|
|
func findCollection(app core.App, name string) (*core.Collection, error) {
|
|
collection, err := app.FindCollectionByNameOrId(name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to find collection %s: %w", name, err)
|
|
}
|
|
return collection, nil
|
|
}
|