Skip to content

Commit

Permalink
Add MongoModelStorage.Configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
colemancda committed Aug 18, 2023
1 parent 2131d30 commit fecab65
Showing 1 changed file with 57 additions and 27 deletions.
84 changes: 57 additions & 27 deletions Sources/MongoDBModel/MongoDatabase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,53 @@ public struct MongoModelStorage: ModelStorage {

public let model: Model

public let options: Configuration

public init(
database: MongoDatabase,
model: Model
model: Model,
options: Configuration = Configuration()
) {
self.database = database
self.model = model
self.options = options
}

/// Fetch managed object.
public func fetch(_ entityName: EntityName, for id: ObjectID) async throws -> ModelData? {
let entity = try model(for: entityName)
return try await database.fetch(entity, for: id)
let options = options.collections[entity.id]
return try await database.fetch(entity, for: id, options: options)
}

/// Fetch managed objects.
public func fetch(_ fetchRequest: FetchRequest) async throws -> [ModelData] {
let entity = try model(for: fetchRequest.entity)
return try await database.fetch(fetchRequest, entity: entity)
let options = options.collections[entity.id]
return try await database.fetch(fetchRequest, entity: entity, options: options)
}

/// Fetch and return result count.
public func count(_ fetchRequest: FetchRequest) async throws -> UInt {
try await database.count(fetchRequest)
let options = options.collections[fetchRequest.entity]
return try await database.count(fetchRequest, options: options)
}

/// Create or edit a managed object.
public func insert(_ value: ModelData) async throws {
try await database.insert(value)
let options = options.collections[value.entity]
try await database.insert(value, options: options)
}

/// Create or edit multiple managed objects.
public func insert(_ values: [ModelData]) async throws {
try await database.insert(values)
try await database.insert(values, options: options.collections)
}

/// Delete the specified managed object.
public func delete(_ entity: EntityName, for id: ObjectID) async throws {
try await database.delete(entity, for: id)
let options = options.collections[entity]
try await database.delete(entity, for: id, options: options)
}

private func model(for entityName: EntityName) throws -> EntityDescription {
Expand All @@ -56,14 +65,27 @@ public struct MongoModelStorage: ModelStorage {
}
}

public extension MongoDatabase {
public extension MongoModelStorage {

struct Configuration {

public var collections: [EntityName: MongoCollectionOptions]

public init(collections: [EntityName : MongoCollectionOptions] = [:]) {
self.collections = collections
}
}
}

internal extension MongoDatabase {

/// Fetch managed object.
func fetch(
_ entity: EntityDescription,
for id: ObjectID
for id: ObjectID,
options: MongoCollectionOptions?
) async throws -> ModelData? {
guard let document = try await find(entity.id, for: id) else {
guard let document = try await find(entity.id, for: id, options: options) else {
return nil
}
return try ModelData(bson: document, model: entity)
Expand All @@ -72,37 +94,47 @@ public extension MongoDatabase {
/// Fetch managed objects.
func fetch(
_ fetchRequest: FetchRequest,
entity: EntityDescription
entity: EntityDescription,
options: MongoCollectionOptions?
) async throws -> [ModelData] {
try await fetchDocuments(fetchRequest)
try await fetchDocuments(fetchRequest, options: options)
.map { try ModelData(bson: $0, model: entity) }
}

/// Fetch and return result count.
func count(_ fetchRequest: FetchRequest) async throws -> UInt {
func count(
_ fetchRequest: FetchRequest,
options: MongoCollectionOptions?
) async throws -> UInt {
let entityName = fetchRequest.entity
let collection = self.collection(entityName)
let collection = self.collection(entityName, options: options)
let filter = fetchRequest.predicate.map { BSONDocument(filter: $0) } ?? [:]
let options = CountDocumentsOptions(fetchRequest: fetchRequest)
let count = try await collection.countDocuments(filter, options: options)
return UInt(count)
}

/// Create or edit a managed object.
func insert(_ value: ModelData) async throws {
func insert(
_ value: ModelData,
options: MongoCollectionOptions?
) async throws {
let entityName = value.entity
let collection = self.collection(entityName)
let collection = self.collection(entityName, options: options)
let document = BSONDocument(model: value)
try await collection.insertOne(document)
}

func insert(_ values: [ModelData]) async throws {
func insert(
_ values: [ModelData],
options: [EntityName: MongoCollectionOptions]
) async throws {
var collections = [EntityName: [ModelData]]()
for value in values {
collections[value.entity, default: []].append(value)
}
for (entity, values) in collections {
let collection = self.collection(entity)
let collection = self.collection(entity, options: options[entity])
let documents = values.map { BSONDocument(model: $0) }
try await collection.insertMany(documents)
}
Expand All @@ -111,23 +143,21 @@ public extension MongoDatabase {
/// Delete the specified managed object.
func delete(
_ entity: EntityName,
for id: ObjectID
for id: ObjectID,
options: MongoCollectionOptions?
) async throws {
let collection = self.collection(entity)
let collection = self.collection(entity, options: options)
let options: DeleteOptions? = nil
let filter: BSONDocument = [
BSONDocument.BuiltInProperty.id.rawValue: .string(id.rawValue)
]
try await collection.deleteOne(filter, options: options)
}
}

internal extension MongoDatabase {

func find(
_ entityName: EntityName,
for id: ObjectID,
options: MongoCollectionOptions? = nil
options: MongoCollectionOptions?
) async throws -> BSONDocument? {
let collection = self.collection(entityName, options: options)
let options: FindOneOptions? = nil
Expand All @@ -139,7 +169,7 @@ internal extension MongoDatabase {

func fetchDocuments(
_ fetchRequest: FetchRequest,
options: MongoCollectionOptions? = nil
options: MongoCollectionOptions?
) async throws -> [BSONDocument] {
let entityName = fetchRequest.entity
let collection = self.collection(entityName, options: options)
Expand All @@ -156,7 +186,7 @@ internal extension MongoDatabase {
func create(
_ entityName: EntityName,
for id: ObjectID,
options: MongoCollectionOptions? = nil
options: MongoCollectionOptions?
) async throws -> BSONDocument {
let collection = self.collection(entityName, options: options)
let document: BSONDocument = [
Expand All @@ -172,7 +202,7 @@ fileprivate extension MongoDatabase {

func collection(
_ name: EntityName,
options: MongoCollectionOptions? = nil
options: MongoCollectionOptions?
) -> MongoCollection<BSONDocument> {
let tableName = name.rawValue.lowercased() + "s"
return collection(tableName, options: options)
Expand Down

0 comments on commit fecab65

Please sign in to comment.