RealmStorage 1.0.4

RealmStorage 1.0.4

Andrew Kochulab 维护。



 
依赖项
Realm>= 0
RealmSwift>= 0
Sourcery>= 0
KeychainSwift>= 0
 

RealmStorage

Realm 数据库的现代包装器 [iOS, macOS, tvOS & watchOS]

快速使用

一个轻松编写代码的方式,强类型查询,快速开发数据层,多线程等更多有趣的功能。

let users = DB.user().objects { query in
   query.add { $0.firstName.isEqual("Robert") }
        .and { $0.events.count().isGreater(thanOrEqual: 5) }
        .and(\.updatedAt.isNotNil)
}.get()

特性

RealmStorage 支持以下操作

  • 模式自动生成
  • 内置数据库迁移
  • 多线程
  • 强类型查询
  • 写入事务
  • 所有 CRUD 操作

如何使用

安装

要将RealmStorage添加到基于Swift Package Manager的项目中,请添加以下内容

.package(url: "https://github.com/AndrewKochulab/RealmStorage.git")

Cocoapods

pod 'RealmStorage'

创建一个新的构建阶段 项目 -> 主目标 -> 构建阶段,并添加以下代码

"$PODS_ROOT/Sourcery/bin/sourcery" --sources "$PODS_ROOT/RealmStorage/Sources/RealmStorage/PredicateFlow/Core/Classes/Utils/" --sources "$SRCROOT" --templates "$PODS_ROOT/RealmStorage/Sources/RealmStorage/PredicateFlow/Core/Templates/PredicateFlow.stencil" --output "$SRCROOT/PredicateFlow.generated.swift" --disableCache

PredicateFlow.generated.swift文件导入到主目标中。

它将自动生成所有用于获取数据库查询所需的模式(详细信息见下文)。

示例

创建表

import RealmSwift
import RealmStorage

final class User: IdentifiableStorageObject, PredicateSchema {
  enum Gender: String {
    case male, female
  }
  
  dynamic var createdAt = Date()
  dynamic var updatedAt: Date?
    
  dynamic var firstName = ""
  dynamic var lastName = ""
    
  private dynamic var genderName = ""
    
  var gender: Gender? {
    get { Gender(rawValue: genderName) }
    set { genderName = newValue?.rawValue ?? "" }
  }
    
  let events = List<Event>()
}

final class Event: IdentifiableStorageObject, PredicateSchema {
  dynamic var date: Date?
  dynamic var name = ""
  dynamic var author: User?
    
  let members = List<EventMember>()
}

final class EventMember: IdentifiableStorageObject, PredicateSchema {
  dynamic var joinedAt = Date()
  dynamic var user: User? {
    didSet {
      updateCompoundID()
    }
  }
    
  dynamic var event: Event? {
    didSet {
      updateCompoundID()
    }
  }
    
  private func updateCompoundID() {
    guard let user = user,
      let event = event else {
        return
    }
        
    self.id = CompoundID(
      items: user.id.value, event.id.value,
      separator: "_"
    )
  }
}

自动生成的模式代码看起来像

感谢 Andrea Del Fante 为 PredicateFlow 库所做的贡献。请见仓库:https://github.com/andreadelfante/PredicateFlow

/// The "User" Predicate Schema
internal struct UserSchema: GeneratedPredicateSchema {
    internal var identifier: StringPredicateProperty { return builder.string("identifier") }
    internal var createdAt: PredicateProperty<Date> { return builder.generic("createdAt") }
    internal var updatedAt: PredicateProperty<Date> { return builder.generic("updatedAt") }
    internal var firstName: StringPredicateProperty { return builder.string("firstName") }
    internal var lastName: StringPredicateProperty { return builder.string("lastName") }
    internal var genderName: StringPredicateProperty { return builder.string("genderName") }
    internal var events: CollectionProperty<EventSchema> { return builder.collection("events") }
}

在事务中保存对象

let user = User().apply {
  $0.id = Identifier(value: "user_id")
  $0.firstName = "Steve"
  $0.lastName = "Rogers"
  $0.gender = .male
}

let event = Event().apply {
  $0.id = Identifier(value: "event_id")
  $0.name = "Avengers Game"
  $0.date = Date().addingTimeInterval(3600 * 10)
  $0.author = user
}

let eventMember = EventMember().apply {
  $0.event = event
  $0.user = user
}.apply {
  event.members.append($0)
}

try DB.perform { transaction in
  transaction.add(
    objects: [user, event, eventMember],
    update: false
  )
}

在事务中更新对象

func update(user: User) throws {
  try DB.user().update(user) {
    $0.firstName = "Tony"
    $0.lastName = "Stark"
  }
}
    
func update(event: Event, newDate: Date) throws {
  try DB.event().update(event) {
    $0.date = newDate
  }
}

同步抓取操作

let users = DB.user().objects { query in
   query.add { $0.firstName.isEqual("Robert") }
        .and { $0.events.count().isGreater(thanOrEqual: 5) }
        .and(\.updatedAt.isNotNil)
}.get()

let user = DB.user().object(by: Identifier(value: "user_id"))

let lastEvent = DB.event().last()
let allEvents = DB.event().all().get()

异步抓取操作

DB.event().first { event in
  if event != nil {
    // do actions
  }
}
        
DB.event().objects(matching: { query in
  query.add { $0.members.count() > 1000 }
  query.sort(by: { $0.date.ascending() })
}, completion: { operation in
  let events = operation.get()
  
  // do some actions
  for event in events {
    print(event.description)
  }
})

创建自己的读取操作

final class ReadCurrentSubscriptionsDatabaseOperation: ReadObjectsDatabaseOperation<Subscription> {
  init(shouldThreadSafe isThreadSafe: Bool = false) {
    super.init(matching: { query in
      query.add(\.hasExpired.isFalse)
      query.sort(by: { $0.expiresAt.descending() })
    }, shouldThreadSafe: isThreadSafe)
  }
}

extension SubscriptionPersistence { 
  func current() -> [Subscription] { 
    ReadCurrentSubscriptionsDatabaseOperation().get()
  }
}

let currentSubscriptions = DB.subscription().current()

// or 

let currentSubscriptions = DB.subscription().objects(matching: { query in
  query.add(\.hasExpired.isFalse)
  query.sort(by: { $0.expiresAt.descending() })
}).get()

贡献

⭐️如果你喜欢你所看到的东西,在GitHub上 star 我们。

发现了一个错误、一个错别字或者某些没被很好地记录的细节吗?我们非常希望你能打开一个问题来告诉我我能改进什么!

欢迎贡献,并且我们非常感激!

许可证

本代码遵照MIT许可证分发。更多信息请查看LICENSE文件。