Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!

01.12.2024

Дев-адвент 1: база даних для Swift: GRDB

#Адвент2024

Не так склалося, як гадалося, Lighter.swift це більше для баз, які складають зміст застосунку. Я про таке використання навіть не здогадувався. Наприклад, можна зробити застосунок-словник, де зміст буде у базі SQLIte, яка вже запакована в пакет застосунку.

Тому обрав GRDB - це просунутіша бібліотека для роботи з SQLite. Чимало нагадує ActiveRecord з Ruby. Має інтеграцію у SwiftUI - GRDBQuery. А порівняно зі SwiftData - це все ж звичайний ORM: будуємо запити, отримуємо структури, зберігаємо назад. Перебіг даних передбачуваний та знайомий.

Схожість з ActiveRecord: Міграції, за синтаксисом та роботою дуже схожі на Rails. Це відразу вища оцінка. Асоціації, практично так само задаються… хоч лінивого завантаження тут немає. Зате є вбудована вибірка та навіть агрегації за асоціаціями — тільки окремим запитом. Побудова структованих запитів на кшталт Arel - хоча як і в AR, можна завжди зробити прямим текстом SQL, що новачку просто рятує життя.

Про запити. Сподобалося, що можна вказати тип для результату будь-якого запиту. Наприклад, вищезгаданий розмір асоціації треба кудись повертати: для того оголошуємо нову структуру:

struct TagAndCount: FetchableRecord {
  var tag: Tag
  var sampleCount: Int
}

Tag.appending(Tag.samples.count).asRequest(of: TagAndCount.self)

Про модель застосунку Також сподобався оцей GRDBQuery. Він автоматично виконує запити, потрібні компоненті SwiftUI. Особливо гарно, що запити для нього задаються у вигляді структурного типу з методом fetch(db). Тож в нього можна запхати не тільки запит, а й перед- та післяобробку. Наприклад. я в одному місці перетворюю результат на Set, бо компоненті так зручніше.

Поки націлений всю логіку переписати на шар запитів, тобто ніякого стану не тримати окремо від бази. Бо та база SQLite теж сидить поруч в памʼяті, до чого ще треба звикнути.