cleanup and add user names services

sync2
Laurent 11 months ago
parent bd7ec4dcc9
commit cef665f166
  1. 1
      LeStorage/Codables/ApiCall.swift
  2. 1
      LeStorage/Codables/DataAccess.swift
  3. 1
      LeStorage/Codables/DataLog.swift
  4. 1
      LeStorage/Codables/FailedAPICall.swift
  5. 1
      LeStorage/Codables/GetSyncData.swift
  6. 1
      LeStorage/Codables/Log.swift
  7. 9
      LeStorage/Services.swift
  8. 7
      LeStorage/Storable.swift
  9. 6
      LeStorage/Store.swift
  10. 60
      LeStorage/StoreCenter.swift
  11. 2
      LeStorageTests/CollectionsTests.swift
  12. 2
      LeStorageTests/IdentifiableTests.swift
  13. 3
      LeStorageTests/StoredCollectionTests.swift

@ -17,7 +17,6 @@ class ApiCall<T: Storable>: ModelObject, Storable, SomeCall {
static func resourceName() -> String { return "apicalls_" + T.resourceName() }
static func tokenExemptedMethods() -> [HTTPMethod] { return [] }
static func filterByStoreIdentifier() -> Bool { return false }
var id: String = Store.randomId()

@ -11,7 +11,6 @@ class DataAccess: SyncedModelObject, SyncedStorable {
static func tokenExemptedMethods() -> [HTTPMethod] { return [] }
static func resourceName() -> String { return "data-access" }
static func filterByStoreIdentifier() -> Bool { return false }
static func relationships() -> [Relationship] { return [] }
var id: String = Store.randomId()

@ -11,7 +11,6 @@ class DataLog: ModelObject, Storable {
static func resourceName() -> String { return "data-logs" }
static func tokenExemptedMethods() -> [HTTPMethod] { return [] }
static func filterByStoreIdentifier() -> Bool { return false }
static func relationships() -> [Relationship] { return [] }
var id: String = Store.randomId()

@ -11,7 +11,6 @@ class FailedAPICall: SyncedModelObject, SyncedStorable {
static func resourceName() -> String { return "failed-api-calls" }
static func tokenExemptedMethods() -> [HTTPMethod] { return [] }
static func filterByStoreIdentifier() -> Bool { return false }
static func relationships() -> [Relationship] { return [] }
var id: String = Store.randomId()

@ -9,7 +9,6 @@ import Foundation
class GetSyncData: SyncedModelObject, SyncedStorable, URLParameterConvertible {
static func filterByStoreIdentifier() -> Bool { return false }
static func tokenExemptedMethods() -> [HTTPMethod] { return [] }
static func resourceName() -> String {

@ -11,7 +11,6 @@ class Log: SyncedModelObject, SyncedStorable {
static func resourceName() -> String { return "logs" }
static func tokenExemptedMethods() -> [HTTPMethod] { return [] }
static func filterByStoreIdentifier() -> Bool { return false }
static func relationships() -> [Relationship] { return [] }
var id: String = Store.randomId()

@ -34,8 +34,8 @@ let postDeviceTokenCall: ServiceCall = ServiceCall(
path: "device-token/", method: .post, requiresToken: true)
let getUserDataAccessCall: ServiceCall = ServiceCall(
path: "user-data-access/", method: .get, requiresToken: true)
let userSearchCall: ServiceCall = ServiceCall(
path: "users-search/", method: .get, requiresToken: true)
let userNamesCall: ServiceCall = ServiceCall(
path: "user-names/", method: .get, requiresToken: true)
/// A class used to send HTTP request to the django server
public class Services {
@ -463,9 +463,8 @@ public class Services {
// MARK: - Others
public func searchUsers(string: String) async throws -> [ShortUser] {
let baseRequest = try self._baseRequest(call: userSearchCall, getArguments: ["search": string])
return try await self._runRequest(baseRequest)
public func getUserNames() async throws -> [ShortUser] {
return try await self._runRequest(serviceCall: userNamesCall)
}
// MARK: - Authentication

@ -17,11 +17,6 @@ public protocol Storable: Codable, Identifiable, NSObjectProtocol {
/// Also used as the name of the local file
static func resourceName() -> String
/// This method is only used if the instance store uses an identifier
/// This method should return true if the resources need to get filtered using the store identifier when performing a GET
/// Returning false won't filter the resources when performing a GET
static func filterByStoreIdentifier() -> Bool
/// A method that deletes the local dependencies of the resource
/// Mimics the behavior the cascading delete on the django server
/// Typically when we delete a resource, we automatically delete items that depends on it,
@ -42,7 +37,7 @@ extension Storable {
}
/// Returns a string id for the instance
var stringId: String {
public var stringId: String {
switch self.id {
case let sp as any StringProtocol:
return String(sp)

@ -243,8 +243,6 @@ final public class Store {
count += collection.referenceCount(type: type, id: id)
}
return count
// let collection: StoredCollection<T> = try self.collection()
// collection.revokeByStringIdNoSync(id)
}
// MARK: - Write
@ -292,8 +290,8 @@ final public class Store {
/// Retrieves all the items on the server
public func getItems<T: SyncedStorable>() async throws -> [T] {
if T.filterByStoreIdentifier() {
return try await StoreCenter.main.getItems(identifier: self.identifier)
if let identifier = self.identifier {
return try await StoreCenter.main.getItems(identifier: identifier)
} else {
return try await StoreCenter.main.getItems()
}

@ -822,39 +822,55 @@ public class StoreCenter {
// MARK: - Data Access
public func giveUserAccess<T: SyncedStorable>(_ user: String, data: T) throws {
// public func giveUserAccess<T: SyncedStorable>(_ user: String, data: T) throws {
// guard let dataAccessCollection = self._dataAccess else {
// throw LeStorageError.dataAccessCollectionNotDefined
// }
// guard let userId = self.userId else {
// throw LeStorageError.cantCreateDataAccessBecauseUserIdIsNil
// }
// let collection: StoredCollection<T> = try Store.main.collection()
// guard collection.findById(data.id) != nil else {
// throw LeStorageError.cantCreateDataAccessBecauseNotInMainStore
// }
//
// if let dataAccess = dataAccessCollection.first(where: { $0.modelId == data.stringId }) {
// dataAccess.sharedWith.append(user)
// dataAccessCollection.addOrUpdate(instance: dataAccess)
// } else {
// let dataAccess = DataAccess(owner: userId, sharedWith: [user], modelName: String(describing: type(of: data)), modelId: data.stringId)
// dataAccessCollection.addOrUpdate(instance: dataAccess)
// }
// }
public func authorizedUsers(for modelId: String) -> [String] {
guard let dataAccessCollection = self._dataAccess else {
throw LeStorageError.dataAccessCollectionNotDefined
}
guard let userId = self.userId else {
throw LeStorageError.cantCreateDataAccessBecauseUserIdIsNil
return []
}
let collection: StoredCollection<T> = try Store.main.collection()
guard collection.findById(data.id) != nil else {
throw LeStorageError.cantCreateDataAccessBecauseNotInMainStore
}
if let dataAccess = dataAccessCollection.first(where: { $0.modelId == data.stringId }) {
dataAccess.sharedWith.append(user)
dataAccessCollection.addOrUpdate(instance: dataAccess)
} else {
let dataAccess = DataAccess(owner: userId, sharedWith: [user], modelName: String(describing: type(of: data)), modelId: data.stringId)
dataAccessCollection.addOrUpdate(instance: dataAccess)
if let dataAccess = dataAccessCollection.first(where: { $0.modelId == modelId }) {
return dataAccess.sharedWith
}
return []
}
public func removeUserAccess<T: SyncedStorable>(_ user: String, data: T) {
public func setAuthorizedUsers<T: SyncedStorable>(for instance: T, users: [String]) throws {
guard let dataAccessCollection = self._dataAccess else {
return
}
if let dataAccess = dataAccessCollection.first(where: { $0.modelId == data.stringId }) {
dataAccess.sharedWith.removeAll(where: { $0 == user })
if dataAccess.sharedWith.isEmpty {
guard let userId = self.userId else {
throw LeStorageError.cantCreateDataAccessBecauseUserIdIsNil
}
if let dataAccess = dataAccessCollection.first(where: { $0.modelId == instance.stringId }) {
if users.isEmpty {
dataAccessCollection.delete(instance: dataAccess)
} else {
dataAccessCollection.addOrUpdate(instance: dataAccess)
dataAccess.sharedWith.removeAll()
dataAccess.sharedWith = users
}
} else {
let dataAccess = DataAccess(owner: userId, sharedWith: users, modelName: String(describing: type(of: instance)), modelId: instance.stringId)
dataAccessCollection.addOrUpdate(instance: dataAccess)
}
}

@ -13,7 +13,6 @@ class Car: ModelObject, Storable {
var id: String = Store.randomId()
static func resourceName() -> String { return "car" }
static func filterByStoreIdentifier() -> Bool { return false }
static var relationshipNames: [String] = []
}
@ -24,7 +23,6 @@ class Boat: ModelObject, SyncedStorable {
static func tokenExemptedMethods() -> [LeStorage.HTTPMethod] { return [] }
static func resourceName() -> String { return "boat" }
static func filterByStoreIdentifier() -> Bool { return false }
static var relationshipNames: [String] = []
var storeId: String? { return nil }

@ -11,7 +11,6 @@ import LeStorage
class IntObject: ModelObject, Storable {
static func resourceName() -> String { "int" }
static func tokenExemptedMethods() -> [LeStorage.HTTPMethod] { [] }
static func filterByStoreIdentifier() -> Bool { false }
static var relationshipNames: [String] = []
var id: Int
@ -26,7 +25,6 @@ class IntObject: ModelObject, Storable {
class StringObject: ModelObject, Storable {
static func resourceName() -> String { "string" }
static func tokenExemptedMethods() -> [LeStorage.HTTPMethod] { [] }
static func filterByStoreIdentifier() -> Bool { false }
static var relationshipNames: [String] = []
var id: String

@ -100,9 +100,6 @@ class StoredCollectionTests: XCTestCase {
// Mock Storable for testing purposes
class MockStorable: ModelObject, Storable {
static func filterByStoreIdentifier() -> Bool {
return false
}
var id: String = Store.randomId()
var name: String

Loading…
Cancel
Save