Skip to content

Commit

Permalink
Merge pull request #1151 from planetary-social/reduce-unecessary-saves
Browse files Browse the repository at this point in the history
Work around duplicate Relays in the database
  • Loading branch information
mplorentz authored May 20, 2024
2 parents 400a8c4 + a81a1d4 commit 04a8bac
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 17 deletions.
1 change: 0 additions & 1 deletion Nos/Models/CoreData/Author+CoreDataClass.swift
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ import Logger

func add(relay: Relay) {
relays.insert(relay)
print("Adding \(relay.address ?? "") to \(hexadecimalPublicKey ?? "")")
}

@MainActor func mute(viewContext context: NSManagedObjectContext) async throws {
Expand Down
11 changes: 10 additions & 1 deletion Nos/Models/CoreData/Event+CoreDataClass.swift
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,17 @@ public class Event: NosManagedObject, VerifiableEvent {
}

@nonobjc public class func event(by identifier: String, seenOn relay: Relay) -> NSFetchRequest<Event> {
guard let relayAddress = relay.address else {
return Event.emptyRequest()
}

let fetchRequest = NSFetchRequest<Event>(entityName: "Event")
fetchRequest.predicate = NSPredicate(format: "identifier = %@ AND ANY seenOnRelays = %@", identifier, relay)
fetchRequest.predicate = NSPredicate(
format: "identifier = %@ AND ANY seenOnRelays.address = %@",
identifier,
relayAddress
)
fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Relay.createdAt, ascending: true)]
fetchRequest.fetchLimit = 1
return fetchRequest
}
Expand Down
3 changes: 2 additions & 1 deletion Nos/Models/CoreData/Relay+CoreDataClass.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public class Relay: NosManagedObject {
@nonobjc public class func relay(by address: String) -> NSFetchRequest<Relay> {
let fetchRequest = NSFetchRequest<Relay>(entityName: "Relay")
fetchRequest.predicate = NSPredicate(format: "address = %@", address)
fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Relay.createdAt, ascending: true)]
fetchRequest.fetchLimit = 1
return fetchRequest
}
Expand Down Expand Up @@ -116,7 +117,7 @@ public class Relay: NosManagedObject {
metadataFetchedAt = Date.now
}

convenience init(context: NSManagedObjectContext, address: String, author: Author? = nil) throws {
private convenience init(context: NSManagedObjectContext, address: String, author: Author? = nil) throws {
guard let addressURL = URL(string: address),
addressURL.scheme == "wss" else {
throw RelayError.invalidAddress
Expand Down
7 changes: 2 additions & 5 deletions Nos/Service/CurrentUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,8 @@ enum CurrentUserError: Error {

// Recommended Relays for new user
for address in Relay.recommended {
_ = try? Relay(
context: viewContext,
address: address,
author: author
)
let relay = try? Relay.findOrCreate(by: address, context: viewContext)
relay?.addToAuthors(author)
}
try viewContext.save()

Expand Down
3 changes: 2 additions & 1 deletion Nos/Views/Discover/DiscoverTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ struct DiscoverTab_Previews: PreviewProvider {
static func createRelayData(in context: NSManagedObjectContext, user: Author) {
let addresses = ["wss://nostr.band", "wss://nos.social", "wss://a.long.domain.name.to.see.what.happens"]
addresses.forEach {
_ = try? Relay(context: previewContext, address: $0, author: user)
let relay = try? Relay.findOrCreate(by: $0, context: previewContext)
relay?.addToAuthors(user)
}

try? previewContext.save()
Expand Down
6 changes: 1 addition & 5 deletions Nos/Views/Onboarding/OnboardingLoginView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ struct OnboardingLoginView: View {

for address in Relay.allKnown {
do {
let relay = try Relay(
context: viewContext,
address: address,
author: currentUser.author
)
let relay = try Relay.findOrCreate(by: address, context: viewContext)
currentUser.onboardingRelays.append(relay)
} catch {
Log.error(error.localizedDescription)
Expand Down
2 changes: 1 addition & 1 deletion Nos/Views/RelayDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ struct RelayDetailView_Previews: PreviewProvider {
static var previewContext = PersistenceController.preview.container.viewContext
static var relay: Relay {
do {
return try Relay(context: previewContext, address: "wss://example.com")
return try Relay.findOrCreate(by: "wss://example.com", context: previewContext)
} catch {
return Relay(context: previewContext)
}
Expand Down
5 changes: 3 additions & 2 deletions Nos/Views/RelayPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ struct RelayPicker_Previews: PreviewProvider {

static func createTestData(in context: NSManagedObjectContext, user: Author) {
let addresses = ["wss://nostr.com", "wss://nos.social", "wss://alongdomainnametoseewhathappens.com"]
addresses.forEach {
addresses.forEach { address in
do {
_ = try Relay(context: previewContext, address: $0, author: user)
let relay = try? Relay.findOrCreate(by: address, context: previewContext)
relay?.addToAuthors(user)
} catch {
print(error)
}
Expand Down
46 changes: 46 additions & 0 deletions NosTests/Model/EventTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,52 @@ final class EventTests: CoreDataTestCase {

XCTAssertEqual(testEvent.repostedNote()?.identifier, nil)
}

// MARK: - Fetch requests

func test_eventByIdentifierSeenOnRelay_givenAlreadySeen() throws {
// Arrange
let eventID = "foo"
let event = try Event.findOrCreateStubBy(id: eventID, context: testContext)
let relay = try Relay.findOrCreate(by: "wss://relay.nos.social", context: testContext)
event.addToSeenOnRelays(relay)
try testContext.saveIfNeeded()

// Act
let events = try testContext.fetch(Event.event(by: eventID, seenOn: relay))

// Assert
XCTAssertEqual(events.count, 1)
XCTAssertEqual(events.first, event)
}

func test_eventByIdentifierSeenOnRelay_givenNotSeen() throws {
// Arrange
let eventID = "foo"
let event = try Event.findOrCreateStubBy(id: eventID, context: testContext)
let relay = try Relay.findOrCreate(by: "wss://relay.nos.social", context: testContext)

// Act
let events = try testContext.fetch(Event.event(by: eventID, seenOn: relay))

// Assert
XCTAssertEqual(events.count, 0)
}

func test_eventByIdentifierSeenOnRelay_givenSeenOnAnother() throws {
// Arrange
let eventID = "foo"
let event = try Event.findOrCreateStubBy(id: eventID, context: testContext)
let relayOne = try Relay.findOrCreate(by: "wss://relay.nos.social", context: testContext)
event.addToSeenOnRelays(relayOne)
let relayTwo = try Relay.findOrCreate(by: "wss://other.relay.com", context: testContext)

// Act
let events = try testContext.fetch(Event.event(by: eventID, seenOn: relayTwo))

// Assert
XCTAssertEqual(events.count, 0)
}

// MARK: - Helpers

Expand Down

0 comments on commit 04a8bac

Please sign in to comment.