can request separate books
parent
9eb488a87a
commit
32696d7b58
|
@ -5,6 +5,8 @@
|
||||||
// Created by Saint on 5/20/24.
|
// Created by Saint on 5/20/24.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import GRDB
|
||||||
|
import GRDBQuery
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import WrappingHStack
|
import WrappingHStack
|
||||||
|
@ -14,8 +16,11 @@ struct SegRow: View {
|
||||||
var ribbonId: Int64
|
var ribbonId: Int64
|
||||||
@State var highlights = Set<Int>()
|
@State var highlights = Set<Int>()
|
||||||
|
|
||||||
|
let intraWordSpacing = CGFloat(1.6)
|
||||||
var body: some View {
|
var body: some View {
|
||||||
var segSplit = seg.body.components(separatedBy: ";;")
|
var segSplit = seg.body.components(separatedBy: ";;")
|
||||||
|
Print("got here meow")
|
||||||
|
Print(segSplit)
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
var retView = WrappingHStack(alignment: .leading, horizontalSpacing: 0) {
|
var retView = WrappingHStack(alignment: .leading, horizontalSpacing: 0) {
|
||||||
ForEach(0 ..< segSplit.count, id: \.self) { segIndex in
|
ForEach(0 ..< segSplit.count, id: \.self) { segIndex in
|
||||||
|
@ -53,7 +58,8 @@ struct SegRow: View {
|
||||||
Text(arrayOfText[index])
|
Text(arrayOfText[index])
|
||||||
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
|
.foregroundColor(Color(UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 1.00)))
|
||||||
.font(Font.custom("AveriaSerifLibre-Regular", size: fontSize))
|
.font(Font.custom("AveriaSerifLibre-Regular", size: fontSize))
|
||||||
.padding(.horizontal, 1.5) // intra word spacing
|
|
||||||
|
.padding(.horizontal, intraWordSpacing) // intra word spacing
|
||||||
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
.if(self.highlights.contains(verse.verse)) { $0.background(Color(hex: highlightColor)) }
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
|
@ -79,7 +85,6 @@ struct SegRow: View {
|
||||||
struct Pane: View {
|
struct Pane: View {
|
||||||
@ObservedObject var paneConnector: PaneConnector
|
@ObservedObject var paneConnector: PaneConnector
|
||||||
|
|
||||||
@State var segs: [SegDenorm]
|
|
||||||
@State var selectedRibbon: [Ribbon]
|
@State var selectedRibbon: [Ribbon]
|
||||||
|
|
||||||
@State var width: CGFloat
|
@State var width: CGFloat
|
||||||
|
@ -89,6 +94,8 @@ struct Pane: View {
|
||||||
|
|
||||||
@State var refresh: Bool = false
|
@State var refresh: Bool = false
|
||||||
|
|
||||||
|
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
|
||||||
|
|
||||||
@Environment(\.appDatabase) private var appDatabase
|
@Environment(\.appDatabase) private var appDatabase
|
||||||
|
|
||||||
// var handleVisibilityChanged: (String, VisibilityChange, VisibilityTracker<String>) -> Void
|
// var handleVisibilityChanged: (String, VisibilityChange, VisibilityTracker<String>) -> Void
|
||||||
|
@ -125,6 +132,9 @@ struct Pane: View {
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
if paneConnector.visibilityTracker == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
let gTracker = paneConnector.visibilityTracker!
|
let gTracker = paneConnector.visibilityTracker!
|
||||||
|
|
||||||
Print("scroll Id target: \(paneConnector.scrollId)")
|
Print("scroll Id target: \(paneConnector.scrollId)")
|
||||||
|
|
|
@ -11,9 +11,9 @@ struct SegDenormRequest: Queryable {
|
||||||
var book: String
|
var book: String
|
||||||
|
|
||||||
// MARK: - Queryable Implementation
|
// MARK: - Queryable Implementation
|
||||||
|
|
||||||
static var defaultValue: [SegDenorm] { [] }
|
static var defaultValue: [SegDenorm] { [] }
|
||||||
|
|
||||||
func publisher(in appDatabase: AppDatabase) -> AnyPublisher<[SegDenorm], Error> {
|
func publisher(in appDatabase: AppDatabase) -> AnyPublisher<[SegDenorm], Error> {
|
||||||
ValueObservation
|
ValueObservation
|
||||||
.tracking(fetchValue(_:))
|
.tracking(fetchValue(_:))
|
||||||
|
@ -22,17 +22,39 @@ struct SegDenormRequest: Queryable {
|
||||||
scheduling: .immediate)
|
scheduling: .immediate)
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchValue(_ db: Database) throws -> [SegDenorm] {
|
|
||||||
print("WOOOOOOF")
|
|
||||||
var sql = "select seg_id as id, seg.book as book, group_concat(line.body, ';;') as body from seg join line on seg.line_id = line.rowid WHERE seg.book = 'bible.john' group by seg.seg_id"
|
|
||||||
|
|
||||||
do {
|
func fetchValue(_ db: Database) throws -> [SegDenorm] {
|
||||||
var ret = try SegDenorm.fetchAll(db, sql: sql) // [Player]
|
print("segs denorm fetching for \(book)")
|
||||||
|
print(book)
|
||||||
// print("SEGS DENORM")
|
var sql = """
|
||||||
// print(ret)
|
select seg_id as id, seg.book as book, group_concat(line.body, ';;') as body from \
|
||||||
|
(select * from seg where seg.book = '\(book)') as seg \
|
||||||
|
join (select * from line where line.book = '\(book)') as line \
|
||||||
|
on seg.line_id = line.line_id group by seg.seg_id
|
||||||
|
"""
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var ret = try SegDenorm.fetchAll(db, sql: sql)
|
||||||
|
|
||||||
|
print("SEGS DENORM")
|
||||||
|
print(ret[0])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// var sql2 = """
|
||||||
|
// select count(1) from seg where seg.book = '\(book)'
|
||||||
|
// """
|
||||||
|
|
||||||
|
// var ret2 = try SegDenorm.fetchAll(db, sql: sql2)
|
||||||
|
|
||||||
|
// print("test sql result")
|
||||||
|
// print(ret2[0])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
} catch let error {
|
} catch let error {
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
print(error)
|
print(error)
|
||||||
|
|
|
@ -24,7 +24,7 @@ struct SelectedRibbonRequest: Queryable {
|
||||||
/// The ordering used by the player request.
|
/// The ordering used by the player request.
|
||||||
// var ordering: Ordering
|
// var ordering: Ordering
|
||||||
static var defaultValue: [Ribbon] { [] }
|
static var defaultValue: [Ribbon] { [] }
|
||||||
|
|
||||||
func publisher(in appDatabase: AppDatabase) -> AnyPublisher<[Ribbon], Error> {
|
func publisher(in appDatabase: AppDatabase) -> AnyPublisher<[Ribbon], Error> {
|
||||||
// Build the publisher from the general-purpose read-only access
|
// Build the publisher from the general-purpose read-only access
|
||||||
// granted by `appDatabase.reader`.
|
// granted by `appDatabase.reader`.
|
||||||
|
@ -39,7 +39,7 @@ struct SelectedRibbonRequest: Queryable {
|
||||||
scheduling: .immediate)
|
scheduling: .immediate)
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is not required by Queryable, but it makes it easier
|
// This method is not required by Queryable, but it makes it easier
|
||||||
func fetchValue(_ db: Database) throws -> [Ribbon] {
|
func fetchValue(_ db: Database) throws -> [Ribbon] {
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ struct SelectedRibbonRequest: Queryable {
|
||||||
// var ret3 = try Ribbon.fetchAll(db, sql: "SELECT * FROM Ribbon") // [Player]
|
// var ret3 = try Ribbon.fetchAll(db, sql: "SELECT * FROM Ribbon") // [Player]
|
||||||
// print(ret3)
|
// print(ret3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// print("FETCH JOIN RIBBON")
|
// print("FETCH JOIN RIBBON")
|
||||||
var ret = try Ribbon.fetchAll(db, sql: "SELECT Ribbon.* FROM SelectedRibbon join Ribbon on SelectedRibbon.ribbonId = ribbon.rowId WHERE SelectedRibbon.rowId = 1") // [Player]
|
var ret = try Ribbon.fetchAll(db, sql: "SELECT Ribbon.* FROM SelectedRibbon join Ribbon on SelectedRibbon.ribbonId = ribbon.rowId WHERE SelectedRibbon.rowId = 1") // [Player]
|
||||||
// print(ret)
|
// print(ret)
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct AppDatabase {
|
||||||
self.dbWriter = dbWriter
|
self.dbWriter = dbWriter
|
||||||
try migrator.migrate(dbWriter)
|
try migrator.migrate(dbWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides access to the database.
|
/// Provides access to the database.
|
||||||
///
|
///
|
||||||
/// Application can use a `DatabasePool`, while SwiftUI previews and tests
|
/// Application can use a `DatabasePool`, while SwiftUI previews and tests
|
||||||
|
@ -19,19 +19,19 @@ struct AppDatabase {
|
||||||
///
|
///
|
||||||
/// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databaseconnections>
|
/// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databaseconnections>
|
||||||
private let dbWriter: any DatabaseWriter
|
private let dbWriter: any DatabaseWriter
|
||||||
|
|
||||||
/// The DatabaseMigrator that defines the database schema.
|
/// The DatabaseMigrator that defines the database schema.
|
||||||
///
|
///
|
||||||
/// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/migrations>
|
/// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/migrations>
|
||||||
private var migrator: DatabaseMigrator {
|
private var migrator: DatabaseMigrator {
|
||||||
var migrator = DatabaseMigrator()
|
var migrator = DatabaseMigrator()
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// Speed up development by nuking the database when migrations change
|
// Speed up development by nuking the database when migrations change
|
||||||
// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/migrations>
|
// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/migrations>
|
||||||
migrator.eraseDatabaseOnSchemaChange = true
|
migrator.eraseDatabaseOnSchemaChange = true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
migrator.registerMigration("createLine") { db in
|
migrator.registerMigration("createLine") { db in
|
||||||
// Create a table
|
// Create a table
|
||||||
// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databaseschema>
|
// See <https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databaseschema>
|
||||||
|
@ -39,6 +39,7 @@ struct AppDatabase {
|
||||||
t.autoIncrementedPrimaryKey("id")
|
t.autoIncrementedPrimaryKey("id")
|
||||||
t.column("body", .text).notNull()
|
t.column("body", .text).notNull()
|
||||||
t.column("chap", .integer).notNull()
|
t.column("chap", .integer).notNull()
|
||||||
|
t.column("line_id", .integer).notNull()
|
||||||
t.column("book", .text).notNull()
|
t.column("book", .text).notNull()
|
||||||
t.column("verse", .integer)
|
t.column("verse", .integer)
|
||||||
}
|
}
|
||||||
|
@ -70,18 +71,19 @@ struct AppDatabase {
|
||||||
t.column("scrollOffset", .integer).notNull()
|
t.column("scrollOffset", .integer).notNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
try db.create(table: "foo2") { t in
|
// change this to nuke/remake the database
|
||||||
|
try db.create(table: "foo1") { t in
|
||||||
t.autoIncrementedPrimaryKey("id")
|
t.autoIncrementedPrimaryKey("id")
|
||||||
t.column("ribbonId", .integer).notNull()
|
t.column("ribbonId", .integer).notNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Migrations for future application versions will be inserted here:
|
// Migrations for future application versions will be inserted here:
|
||||||
// migrator.registerMigration(...) { db in
|
// migrator.registerMigration(...) { db in
|
||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return migrator
|
return migrator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,9 +136,9 @@ extension AppDatabase {
|
||||||
if (newPos < oldPos) {
|
if (newPos < oldPos) {
|
||||||
|
|
||||||
try db.execute(sql: """
|
try db.execute(sql: """
|
||||||
UPDATE Ribbon
|
UPDATE Ribbon
|
||||||
SET pos =
|
SET pos =
|
||||||
CASE
|
CASE
|
||||||
WHEN pos = ? THEN ?
|
WHEN pos = ? THEN ?
|
||||||
ELSE
|
ELSE
|
||||||
pos + 1
|
pos + 1
|
||||||
|
@ -148,9 +150,9 @@ extension AppDatabase {
|
||||||
print("DIFFFFF")
|
print("DIFFFFF")
|
||||||
|
|
||||||
try db.execute(sql: """
|
try db.execute(sql: """
|
||||||
UPDATE Ribbon
|
UPDATE Ribbon
|
||||||
SET pos =
|
SET pos =
|
||||||
CASE
|
CASE
|
||||||
WHEN pos = ? THEN ?
|
WHEN pos = ? THEN ?
|
||||||
ELSE
|
ELSE
|
||||||
pos - 1
|
pos - 1
|
||||||
|
@ -161,7 +163,7 @@ extension AppDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// try db.execute(sql: """
|
// try db.execute(sql: """
|
||||||
// UPDATE Ribbon
|
// UPDATE Ribbon
|
||||||
// SET pos = ?
|
// SET pos = ?
|
||||||
// WHERE (id = ?)
|
// WHERE (id = ?)
|
||||||
// """, arguments: [newPos, ribbon.id!])
|
// """, arguments: [newPos, ribbon.id!])
|
||||||
|
@ -212,27 +214,36 @@ extension AppDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func importJson(_ filename: String, _ db: Database) throws {
|
func importJson(_ filename: String, _ db: Database) throws {
|
||||||
let importJson : JsonImport = load(filename)
|
let importJson: JsonImport = load(filename)
|
||||||
|
|
||||||
if try Line.all().isEmpty(db) {
|
var x = 0
|
||||||
for l in importJson.lines {
|
// if try Line.all().isEmpty(db) {
|
||||||
print("importing Lines")
|
for l in importJson.lines {
|
||||||
_ = try l.inserted(db)
|
// print("importing Lines")
|
||||||
|
if x < 5 {
|
||||||
|
print(l)
|
||||||
|
x += 1
|
||||||
}
|
}
|
||||||
|
_ = try l.inserted(db)
|
||||||
|
}
|
||||||
|
|
||||||
for l in importJson.segs {
|
x = 0
|
||||||
print("importing SEGS")
|
for l in importJson.segs {
|
||||||
_ = try l.inserted(db)
|
// print("importing SEGS")
|
||||||
|
|
||||||
|
if x < 5 {
|
||||||
|
print(l)
|
||||||
|
x += 1
|
||||||
}
|
}
|
||||||
|
_ = try l.inserted(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create random Lines if the database is empty.
|
/// Create random Lines if the database is empty.
|
||||||
func initDatabase() throws {
|
func initDatabase() throws {
|
||||||
|
do {
|
||||||
try dbWriter.write { db in
|
try dbWriter.write { db in
|
||||||
|
|
||||||
if try Line.all().isEmpty(db) {
|
if try Line.all().isEmpty(db) {
|
||||||
|
|
||||||
try importJson("john_export.json", db)
|
try importJson("john_export.json", db)
|
||||||
try importJson("mark_export.json", db)
|
try importJson("mark_export.json", db)
|
||||||
_ = try Ribbon(id: 1, pos: 1, title: "John", book: "bible.john", scrollId: "1", scrollOffset: 0).inserted(db)
|
_ = try Ribbon(id: 1, pos: 1, title: "John", book: "bible.john", scrollId: "1", scrollOffset: 0).inserted(db)
|
||||||
|
@ -241,6 +252,11 @@ extension AppDatabase {
|
||||||
_ = try SelectedRibbon(id: 1, ribbonId: 1).inserted(db)
|
_ = try SelectedRibbon(id: 1, ribbonId: 1).inserted(db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch {
|
||||||
|
print("Error info: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,14 +214,13 @@ struct ContentView: View {
|
||||||
@State var readOffset = CGPoint()
|
@State var readOffset = CGPoint()
|
||||||
@State var dragOffset = CGFloat()
|
@State var dragOffset = CGFloat()
|
||||||
|
|
||||||
|
@Query(SegDenormRequest(book: "bible.john")) private var segs: [SegDenorm]
|
||||||
|
|
||||||
@State var draggedRibbon: Ribbon?
|
@State var draggedRibbon: Ribbon?
|
||||||
@State var isDragging = false
|
@State var isDragging = false
|
||||||
|
|
||||||
@Environment(\.appDatabase) private var appDatabase
|
@Environment(\.appDatabase) private var appDatabase
|
||||||
|
|
||||||
@Query(SegDenormRequest(book: "bible.mark")) private var segs: [SegDenorm]
|
|
||||||
|
|
||||||
@Query(RibbonRequest()) private var ribbons: [Ribbon]
|
@Query(RibbonRequest()) private var ribbons: [Ribbon]
|
||||||
@Query<SelectedRibbonRequest> var selectedRibbon: [Ribbon]
|
@Query<SelectedRibbonRequest> var selectedRibbon: [Ribbon]
|
||||||
|
|
||||||
|
@ -273,7 +272,6 @@ struct ContentView: View {
|
||||||
VStack {
|
VStack {
|
||||||
// Top pane
|
// Top pane
|
||||||
Pane(paneConnector: paneConnector,
|
Pane(paneConnector: paneConnector,
|
||||||
segs: segs,
|
|
||||||
selectedRibbon: selectedRibbon,
|
selectedRibbon: selectedRibbon,
|
||||||
width: geometry.size.width - 50,
|
width: geometry.size.width - 50,
|
||||||
height: geometry.size.height / 2)
|
height: geometry.size.height / 2)
|
||||||
|
|
|
@ -1,39 +1,17 @@
|
||||||
import GRDB
|
import GRDB
|
||||||
/// The Line struct.
|
/// The Line struct.
|
||||||
///
|
|
||||||
/// Identifiable conformance supports SwiftUI list animations, and type-safe
|
|
||||||
/// GRDB primary key methods.
|
|
||||||
/// Equatable conformance supports tests.
|
|
||||||
struct Line: Identifiable, Equatable {
|
struct Line: Identifiable, Equatable {
|
||||||
/// The player id.
|
|
||||||
///
|
|
||||||
/// Int64 is the recommended type for auto-incremented database ids.
|
|
||||||
/// Use nil for players that are not inserted yet in the database.
|
|
||||||
var id: Int64?
|
var id: Int64?
|
||||||
var chap: Int
|
var chap: Int
|
||||||
|
var line_id: Int // this is a line_id per book
|
||||||
var verse: Int
|
var verse: Int
|
||||||
var body: String
|
var body: String
|
||||||
var book: String
|
var book: String
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Line {
|
extension Line {
|
||||||
|
|
||||||
private static let books = [
|
private static let books = [
|
||||||
"John", "Matthew", "Imitation of Christ"]
|
"John", "Matthew", "Imitation of Christ"]
|
||||||
|
|
||||||
/// Creates a new player with empty name and zero score
|
|
||||||
// static func new() -> Line {
|
|
||||||
// Line(id: nil, chap: 1, body: "")
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// Returns a random score
|
|
||||||
static func randomScore() -> Int {
|
|
||||||
10 * Int.random(in: 0...100)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func randomBook() -> String {
|
|
||||||
books.randomElement()!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Persistence
|
// MARK: - Persistence
|
||||||
|
@ -47,7 +25,7 @@ extension Line: Codable, FetchableRecord, MutablePersistableRecord {
|
||||||
static let id = Column(CodingKeys.id)
|
static let id = Column(CodingKeys.id)
|
||||||
static let chap = Column(CodingKeys.chap)
|
static let chap = Column(CodingKeys.chap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates a player id after it has been inserted in the database.
|
/// Updates a player id after it has been inserted in the database.
|
||||||
mutating func didInsert(_ inserted: InsertionSuccess) {
|
mutating func didInsert(_ inserted: InsertionSuccess) {
|
||||||
id = inserted.rowID
|
id = inserted.rowID
|
||||||
|
@ -73,7 +51,7 @@ extension DerivableRequest<Line> {
|
||||||
// // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison
|
// // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison
|
||||||
// order(Line.Columns.name.collating(.localizedCaseInsensitiveCompare))
|
// order(Line.Columns.name.collating(.localizedCaseInsensitiveCompare))
|
||||||
//}
|
//}
|
||||||
|
|
||||||
///// A request of players ordered by score.
|
///// A request of players ordered by score.
|
||||||
/////
|
/////
|
||||||
///// For example:
|
///// For example:
|
||||||
|
|
|
@ -26,11 +26,11 @@ struct LineRequest: Queryable {
|
||||||
var ordering: Ordering
|
var ordering: Ordering
|
||||||
var book: String
|
var book: String
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Queryable Implementation
|
// MARK: - Queryable Implementation
|
||||||
|
|
||||||
static var defaultValue: [Line] { [] }
|
static var defaultValue: [Line] { [] }
|
||||||
|
|
||||||
func publisher(in appDatabase: AppDatabase) -> AnyPublisher<[Line], Error> {
|
func publisher(in appDatabase: AppDatabase) -> AnyPublisher<[Line], Error> {
|
||||||
// Build the publisher from the general-purpose read-only access
|
// Build the publisher from the general-purpose read-only access
|
||||||
// granted by `appDatabase.reader`.
|
// granted by `appDatabase.reader`.
|
||||||
|
@ -45,15 +45,16 @@ struct LineRequest: Queryable {
|
||||||
scheduling: .immediate)
|
scheduling: .immediate)
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is not required by Queryable, but it makes it easier
|
// This method is not required by Queryable, but it makes it easier
|
||||||
// to test LineRequest.
|
// to test LineRequest.
|
||||||
func fetchValue(_ db: Database) throws -> [Line] {
|
func fetchValue(_ db: Database) throws -> [Line] {
|
||||||
if book == "" {
|
return try Line.filter(bookColumn == book).fetchAll(db)
|
||||||
return try Line.filter(bookColumn == Line.randomBook()).fetchAll(db)
|
// if book == "" {
|
||||||
} else {
|
// return try Line.filter(bookColumn == Line.randomBook()).fetchAll(db)
|
||||||
return try Line.filter(bookColumn == book).fetchAll(db)
|
// } else {
|
||||||
}
|
// return try Line.filter(bookColumn == book).fetchAll(db)
|
||||||
|
// }
|
||||||
// switch ordering {
|
// switch ordering {
|
||||||
// case .byScore:
|
// case .byScore:
|
||||||
// return try Line.all().fetchAll(db)
|
// return try Line.all().fetchAll(db)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Foundation
|
||||||
extension AppDatabase {
|
extension AppDatabase {
|
||||||
/// The database for the application
|
/// The database for the application
|
||||||
static let shared = makeShared()
|
static let shared = makeShared()
|
||||||
|
|
||||||
private static func makeShared() -> AppDatabase {
|
private static func makeShared() -> AppDatabase {
|
||||||
do {
|
do {
|
||||||
// Pick a folder for storing the SQLite database, as well as
|
// Pick a folder for storing the SQLite database, as well as
|
||||||
|
@ -20,18 +20,18 @@ extension AppDatabase {
|
||||||
if CommandLine.arguments.contains("-reset") {
|
if CommandLine.arguments.contains("-reset") {
|
||||||
try? fileManager.removeItem(at: folderURL)
|
try? fileManager.removeItem(at: folderURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the database folder if needed
|
// Create the database folder if needed
|
||||||
try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true)
|
try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true)
|
||||||
|
|
||||||
// Connect to a database on disk
|
// Connect to a database on disk
|
||||||
// See https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databaseconnections
|
// See https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databaseconnections
|
||||||
let dbURL = folderURL.appendingPathComponent("db.sqlite")
|
let dbURL = folderURL.appendingPathComponent("db.sqlite")
|
||||||
let dbPool = try DatabasePool(path: dbURL.path)
|
let dbPool = try DatabasePool(path: dbURL.path)
|
||||||
|
|
||||||
// Create the AppDatabase
|
// Create the AppDatabase
|
||||||
let appDatabase = try AppDatabase(dbPool)
|
let appDatabase = try AppDatabase(dbPool)
|
||||||
|
|
||||||
// // Prepare the database with test fixtures if requested
|
// // Prepare the database with test fixtures if requested
|
||||||
// if CommandLine.arguments.contains("-fixedTestData") {
|
// if CommandLine.arguments.contains("-fixedTestData") {
|
||||||
// try appDatabase.createPlayersForUITests()
|
// try appDatabase.createPlayersForUITests()
|
||||||
|
@ -40,9 +40,10 @@ extension AppDatabase {
|
||||||
// // demo purpose.
|
// // demo purpose.
|
||||||
// try appDatabase.createRandomPlayersIfEmpty()
|
// try appDatabase.createRandomPlayersIfEmpty()
|
||||||
// }
|
// }
|
||||||
|
print("initing database")
|
||||||
try appDatabase.initDatabase()
|
try appDatabase.initDatabase()
|
||||||
|
|
||||||
|
|
||||||
return appDatabase
|
return appDatabase
|
||||||
} catch {
|
} catch {
|
||||||
// Replace this implementation with code to handle the error appropriately.
|
// Replace this implementation with code to handle the error appropriately.
|
||||||
|
@ -57,7 +58,7 @@ extension AppDatabase {
|
||||||
fatalError("Unresolved error \(error)")
|
fatalError("Unresolved error \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an empty database for SwiftUI previews
|
/// Creates an empty database for SwiftUI previews
|
||||||
static func empty() -> AppDatabase {
|
static func empty() -> AppDatabase {
|
||||||
// Connect to an in-memory database
|
// Connect to an in-memory database
|
||||||
|
@ -65,7 +66,7 @@ extension AppDatabase {
|
||||||
let dbQueue = try! DatabaseQueue()
|
let dbQueue = try! DatabaseQueue()
|
||||||
return try! AppDatabase(dbQueue)
|
return try! AppDatabase(dbQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a database full of random players for SwiftUI previews
|
/// Creates a database full of random players for SwiftUI previews
|
||||||
static func random() -> AppDatabase {
|
static func random() -> AppDatabase {
|
||||||
let appDatabase = empty()
|
let appDatabase = empty()
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue