Skip to content

Commit

Permalink
last commit before PR
Browse files Browse the repository at this point in the history
  • Loading branch information
leogdion committed Oct 16, 2024
1 parent 0663086 commit a294e01
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 264 deletions.
4 changes: 0 additions & 4 deletions Sources/DataThespian/Databases/Database+ModelContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@
try await self.withModelContext { try $0.delete(where: predicate) }
}

// public func insert(_ closuer: @Sendable @escaping () -> some PersistentModel) async
// -> PersistentIdentifier
// { await self.withModelContext { $0.insert(closuer) } }

public func fetch<T, U: Sendable>(
_ selectDescriptor: @escaping @Sendable () -> FetchDescriptor<T>,
with closure: @escaping @Sendable ([T]) throws -> U
Expand Down
66 changes: 34 additions & 32 deletions Sources/DataThespian/Databases/Database+Queryable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,45 +27,47 @@
// OTHER DEALINGS IN THE SOFTWARE.
//

public import SwiftData
#if canImport(SwiftData)
public import SwiftData

extension Database {
public func save() async throws {
try await self.withModelContext { try $0.save() }
}
extension Database {
public func save() async throws {
try await self.withModelContext { try $0.save() }
}

public func insert<PersistentModelType: PersistentModel, U: Sendable>(
_ closuer: @Sendable @escaping () -> PersistentModelType,
with closure: @escaping @Sendable (PersistentModelType) throws -> U
) async rethrows -> U {
try await self.withModelContext {
try $0.insert(closuer, with: closure)
public func insert<PersistentModelType: PersistentModel, U: Sendable>(
_ closuer: @Sendable @escaping () -> PersistentModelType,
with closure: @escaping @Sendable (PersistentModelType) throws -> U
) async rethrows -> U {
try await self.withModelContext {
try $0.insert(closuer, with: closure)
}
}
}

public func getOptional<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType?) throws -> U
) async rethrows -> U {
try await self.withModelContext {
try $0.getOptional(for: selector, with: closure)
public func getOptional<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType?) throws -> U
) async rethrows -> U {
try await self.withModelContext {
try $0.getOptional(for: selector, with: closure)
}
}
}

public func fetch<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.List,
with closure: @escaping @Sendable ([PersistentModelType]) throws -> U
) async rethrows -> U {
try await self.withModelContext {
try $0.fetch(for: selector, with: closure)
public func fetch<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.List,
with closure: @escaping @Sendable ([PersistentModelType]) throws -> U
) async rethrows -> U {
try await self.withModelContext {
try $0.fetch(for: selector, with: closure)
}
}
}

public func delete<PersistentModelType>(_ selector: Selector<PersistentModelType>.Delete)
async throws
{
try await self.withModelContext {
try $0.delete(selector)
public func delete<PersistentModelType>(_ selector: Selector<PersistentModelType>.Delete)
async throws
{
try await self.withModelContext {
try $0.delete(selector)
}
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
//

#if canImport(SwiftUI)
#if canImport(SwiftUI) && canImport(SwiftData)
import Foundation
import SwiftData
public import SwiftUI
Expand Down
10 changes: 6 additions & 4 deletions Sources/DataThespian/Databases/QueryError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
//

public import SwiftData
#if canImport(SwiftData)
public import SwiftData

public enum QueryError<PersistentModelType: PersistentModel>: Error {
case itemNotFound(Selector<PersistentModelType>.Get)
}
public enum QueryError<PersistentModelType: PersistentModel>: Error {
case itemNotFound(Selector<PersistentModelType>.Get)
}
#endif
170 changes: 86 additions & 84 deletions Sources/DataThespian/Databases/Queryable+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,109 +27,111 @@
// OTHER DEALINGS IN THE SOFTWARE.
//

public import SwiftData
#if canImport(SwiftData)
public import SwiftData

extension Queryable {
@discardableResult
public func insert<PersistentModelType: PersistentModel>(
_ closuer: @Sendable @escaping () -> PersistentModelType
) async -> Model<PersistentModelType> {
await self.insert(closuer, with: Model.init)
}
extension Queryable {
@discardableResult
public func insert<PersistentModelType: PersistentModel>(
_ closuer: @Sendable @escaping () -> PersistentModelType
) async -> Model<PersistentModelType> {
await self.insert(closuer, with: Model.init)
}

public func getOptional<PersistentModelType>(
for selector: Selector<PersistentModelType>.Get
) async -> Model<PersistentModelType>? {
await self.getOptional(for: selector) { persistentModel in
persistentModel.flatMap(Model.init)
public func getOptional<PersistentModelType>(
for selector: Selector<PersistentModelType>.Get
) async -> Model<PersistentModelType>? {
await self.getOptional(for: selector) { persistentModel in
persistentModel.flatMap(Model.init)
}
}
}

public func fetch<PersistentModelType>(
for selector: Selector<PersistentModelType>.List
) async -> [Model<PersistentModelType>] {
await self.fetch(for: selector) { persistentModels in
persistentModels.map(Model.init)
public func fetch<PersistentModelType>(
for selector: Selector<PersistentModelType>.List
) async -> [Model<PersistentModelType>] {
await self.fetch(for: selector) { persistentModels in
persistentModels.map(Model.init)
}
}
}

public func get<PersistentModelType>(
for selector: Selector<PersistentModelType>.Get
) async throws -> Model<PersistentModelType> {
try await self.getOptional(for: selector) { persistentModel in
guard let persistentModel else {
throw QueryError<PersistentModelType>.itemNotFound(selector)
public func get<PersistentModelType>(
for selector: Selector<PersistentModelType>.Get
) async throws -> Model<PersistentModelType> {
try await self.getOptional(for: selector) { persistentModel in
guard let persistentModel else {
throw QueryError<PersistentModelType>.itemNotFound(selector)
}
return Model(persistentModel)
}
return Model(persistentModel)
}
}

public func get<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType) throws -> U
) async throws -> U {
try await self.getOptional(for: selector) { persistentModel in
guard let persistentModel else {
throw QueryError<PersistentModelType>.itemNotFound(selector)
public func get<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType) throws -> U
) async throws -> U {
try await self.getOptional(for: selector) { persistentModel in
guard let persistentModel else {
throw QueryError<PersistentModelType>.itemNotFound(selector)
}
return try closure(persistentModel)
}
return try closure(persistentModel)
}
}

public func update<PersistentModelType>(
for selector: Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType) throws -> Void
) async throws {
try await self.get(for: selector, with: closure)
}
public func update<PersistentModelType>(
for selector: Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType) throws -> Void
) async throws {
try await self.get(for: selector, with: closure)
}

public func update<PersistentModelType>(
for selector: Selector<PersistentModelType>.List,
with closure: @escaping @Sendable ([PersistentModelType]) throws -> Void
) async throws {
try await self.fetch(for: selector, with: closure)
}
public func update<PersistentModelType>(
for selector: Selector<PersistentModelType>.List,
with closure: @escaping @Sendable ([PersistentModelType]) throws -> Void
) async throws {
try await self.fetch(for: selector, with: closure)
}

public func insertIf<PersistentModelType>(
_ model: @Sendable @escaping () -> PersistentModelType,
notExist selector: @Sendable @escaping (PersistentModelType) ->
Selector<PersistentModelType>.Get
) async -> Model<PersistentModelType> {
let persistentModel = model()
let selector = selector(persistentModel)
let modelOptional = await self.getOptional(for: selector)
public func insertIf<PersistentModelType>(
_ model: @Sendable @escaping () -> PersistentModelType,
notExist selector: @Sendable @escaping (PersistentModelType) ->
Selector<PersistentModelType>.Get
) async -> Model<PersistentModelType> {
let persistentModel = model()
let selector = selector(persistentModel)
let modelOptional = await self.getOptional(for: selector)

if let modelOptional {
return modelOptional
} else {
return await self.insert(model)
if let modelOptional {
return modelOptional
} else {
return await self.insert(model)
}
}
}

public func insertIf<PersistentModelType, U: Sendable>(
_ model: @Sendable @escaping () -> PersistentModelType,
notExist selector: @Sendable @escaping (PersistentModelType) ->
Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType) throws -> U
) async throws -> U {
let model = await self.insertIf(model, notExist: selector)
return try await self.get(for: .model(model), with: closure)
public func insertIf<PersistentModelType, U: Sendable>(
_ model: @Sendable @escaping () -> PersistentModelType,
notExist selector: @Sendable @escaping (PersistentModelType) ->
Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType) throws -> U
) async throws -> U {
let model = await self.insertIf(model, notExist: selector)
return try await self.get(for: .model(model), with: closure)
}
}
}

extension Queryable {
public func deleteModels<PersistentModelType>(_ models: [Model<PersistentModelType>]) async throws
{
try await withThrowingTaskGroup(
of: Void.self,
body: { group in
for model in models {
group.addTask {
try await self.delete(.model(model))
extension Queryable {
public func deleteModels<PersistentModelType>(_ models: [Model<PersistentModelType>]) async throws
{
try await withThrowingTaskGroup(
of: Void.self,
body: { group in
for model in models {
group.addTask {
try await self.delete(.model(model))
}
}
try await group.waitForAll()
}
try await group.waitForAll()
}
)
)
}
}
}
#endif
36 changes: 19 additions & 17 deletions Sources/DataThespian/Databases/Queryable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,27 @@
// OTHER DEALINGS IN THE SOFTWARE.
//

public import SwiftData
#if canImport(SwiftData)
public import SwiftData

public protocol Queryable: Sendable {
func save() async throws
public protocol Queryable: Sendable {
func save() async throws

func insert<PersistentModelType: PersistentModel, U: Sendable>(
_ closuer: @Sendable @escaping () -> PersistentModelType,
with closure: @escaping @Sendable (PersistentModelType) throws -> U
) async rethrows -> U
func insert<PersistentModelType: PersistentModel, U: Sendable>(
_ closuer: @Sendable @escaping () -> PersistentModelType,
with closure: @escaping @Sendable (PersistentModelType) throws -> U
) async rethrows -> U

func getOptional<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType?) throws -> U
) async rethrows -> U
func getOptional<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.Get,
with closure: @escaping @Sendable (PersistentModelType?) throws -> U
) async rethrows -> U

func fetch<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.List,
with closure: @escaping @Sendable ([PersistentModelType]) throws -> U
) async rethrows -> U
func fetch<PersistentModelType, U: Sendable>(
for selector: Selector<PersistentModelType>.List,
with closure: @escaping @Sendable ([PersistentModelType]) throws -> U
) async rethrows -> U

func delete<PersistentModelType>(_ selector: Selector<PersistentModelType>.Delete) async throws
}
func delete<PersistentModelType>(_ selector: Selector<PersistentModelType>.Delete) async throws
}
#endif
Loading

0 comments on commit a294e01

Please sign in to comment.