You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.8 KiB
84 lines
2.8 KiB
//
|
|
// Storable.swift
|
|
// LeStorage
|
|
//
|
|
// Created by Laurent Morvillier on 03/02/2024.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/// A protocol describing classes that can be stored locally in JSON and synchronized on our django server
|
|
public protocol Storable: Codable, Identifiable, NSObjectProtocol {
|
|
|
|
/// The store containing a reference to the instance
|
|
var store: Store? { get set }
|
|
|
|
/// The resource name corresponding to the resource path on the API
|
|
/// Also used as the name of the local file
|
|
static func resourceName() -> String
|
|
|
|
/// A method that deletes the local dependencies of the resource
|
|
/// Mimics the behavior of the cascading delete on the django server
|
|
/// Typically when we delete a resource, we automatically delete items that depends on it,
|
|
/// so when we do that on the server, we also need to do it locally
|
|
func deleteDependencies(store: Store, actionOption: ActionOption)
|
|
|
|
/// A method that deletes dependencies of shared resources, but only if they are themselves shared
|
|
/// and not referenced by other objects in the store
|
|
/// This is used when cleaning up shared objects that are no longer in use
|
|
func deleteUnusedSharedDependencies(store: Store)
|
|
|
|
/// Copies the content of another item into the instance
|
|
/// This behavior has been made to get live updates when looking at properties in SwiftUI screens
|
|
func copy(from other: any Storable)
|
|
|
|
/// This method returns RelationShips objects of the type
|
|
static func relationships() -> [Relationship]
|
|
static func parentRelationships() -> [Relationship]
|
|
static func childrenRelationships() -> [Relationship]
|
|
|
|
static func storeParent() -> Bool
|
|
|
|
}
|
|
|
|
extension Storable {
|
|
|
|
/// Returns a filename for the class type
|
|
static func fileName() -> String {
|
|
return self.resourceName() + ".json"
|
|
}
|
|
|
|
/// Returns a string id for the instance
|
|
public var stringId: String {
|
|
switch self.id {
|
|
case let sp as any StringProtocol:
|
|
return String(sp)
|
|
case let intLitteral as any ExpressibleByIntegerLiteral:
|
|
return "\(intLitteral)"
|
|
default:
|
|
fatalError("id not convertible to string")
|
|
}
|
|
}
|
|
|
|
/// Returns the relative path of the instance for the django server
|
|
static func path(id: String? = nil) -> String {
|
|
var path = self.resourceName() + "/"
|
|
if let id {
|
|
path.append(id)
|
|
path.append("/")
|
|
}
|
|
return path
|
|
}
|
|
|
|
static func buildRealId(id: String) -> ID {
|
|
switch ID.self {
|
|
case is String.Type:
|
|
return id as! ID
|
|
case is Int64.Type:
|
|
return Formatter.number.number(from: id)?.int64Value as! ID
|
|
default:
|
|
fatalError("ID \(type(of: ID.self)) is neither String nor Int, can't parse \(id)")
|
|
}
|
|
}
|
|
|
|
}
|
|
|