Skip to content

Instantly share code, notes, and snippets.

@IniongunIsaac
Created April 24, 2021 09:43
Show Gist options
  • Save IniongunIsaac/5d506cb43706eecdb5330b1110ba528c to your computer and use it in GitHub Desktop.
Save IniongunIsaac/5d506cb43706eecdb5330b1110ba528c to your computer and use it in GitHub Desktop.
A combination of Realm and Rx with easy, out of the box CRUD abstractions. Depends on 'RealmSwift, RxRealm and RxSwift'
import RxSwift
import RealmSwift
import RxRealm
class BaseRealmDatasource {
var kRealm: Realm { preconditionFailure("Subclass of BaseRealmDatasource must provide an instance of Realm!") }
func getAll<T: Object>(obj: T.Type) -> Observable<[T]> {
Observable.array(from: kRealm.objects(T.self))
}
func insert<T: Object>(objs: [T]) -> Observable<Void> {
kRealm.insertItems(items: objs)
}
func delete<T: Object>(objs: [T]) -> Observable<Void> {
kRealm.deleteItems(items: objs)
}
func deleteAll<T: Object>(obj: T.Type) -> Observable<Void> {
kRealm.deleteAllItems(for: T.self)
}
func getById<T: Object>(obj: T.Type, id: Any) -> Observable<T> {
Observable.from(optional: kRealm.object(ofType: T.self, forPrimaryKey: id))
}
func getByProperty<T: Object>(obj: T.Type, property: String, value: Any) -> Observable<T> {
Observable.from(optional: kRealm.objects(T.self).filter("\(property) LIKE %@", value).first)
}
func getByPropertyList<T: Object>(obj: T.Type, property: String, value: Any) -> Observable<[T]> {
Observable.from(optional: kRealm.objects(T.self).filter("\(property) LIKE %@", value).toArray())
}
}
import RxSwift
protocol IMenuItemLocalDataSource {
func getAllMenuItems() -> Observable<[MenuItem]>
func getMenuItemById(menuItemId: Int) -> Observable<MenuItem>
func getMenuItemByName(menuItemName: String) -> Observable<MenuItem>
func insertMenuItems(menuItems: [MenuItem]) -> Observable<Void>
func deleteMenuItems(menuItems: [MenuItem]) -> Observable<Void>
func deleteAllMenuItems() -> Observable<Void>
}
import RealmSwift
@objcMembers class MenuItem: Object, Codable {
dynamic var barcode: String? = nil
dynamic var buyPrice: Double = 0.0
dynamic var defaultSellPortion: Int? = nil
dynamic var descriptionText: String? = nil
dynamic var disableWhenStockAmountIsZero: Bool? = nil
dynamic var discountRate: Double? = nil
dynamic var fractionalUnit: Bool? = nil
dynamic var id: Int = 0
dynamic var image: String? = nil
dynamic var imageFile: String? = nil
dynamic var name: String = ""
dynamic var preparationTime: String? = nil
dynamic var price: Double = 0.0
dynamic var showImageOnly: Bool? = nil
dynamic var sortOrder: Int? = nil
dynamic var stockAmount: Double? = nil
dynamic var taxGroupId: String? = nil
dynamic var unitName: String? = nil
dynamic var visible: Bool? = nil
override class func primaryKey() -> String? { "id" }
enum CodingKeys: String, CodingKey {
case id, barcode, buyPrice, defaultSellPortion, descriptionText = "description", disableWhenStockAmountIsZero, discountRate, fractionalUnit, image, imageFile, name, preparationTime, price, showImageOnly, sortOrder, stockAmount, taxGroupId, unitName, visible
}
}
import RxSwift
import RealmSwift
import RxRealm
class MenuItemLocalDataSourceImpl: BaseRealmDatasource, IMenuItemLocalDataSource {
fileprivate let realm: Realm!
init(realm: Realm) {
self.realm = realm
}
func getAllMenuItems() -> Observable<[MenuItem]> {
getAll(obj: MenuItem.self)
}
func getMenuItemById(menuItemId: Int) -> Observable<MenuItem> {
getById(obj: MenuItem.self, id: menuItemId)
}
func getMenuItemByName(menuItemName: String) -> Observable<MenuItem> {
getByProperty(obj: MenuItem.self, property: "name", value: menuItemName)
}
func insertMenuItems(menuItems: [MenuItem]) -> Observable<Void> {
insert(objs: menuItems)
}
func deleteMenuItems(menuItems: [MenuItem]) -> Observable<Void> {
delete(objs: menuItems)
}
func deleteAllMenuItems() -> Observable<Void> {
deleteAll(obj: MenuItem.self)
}
}
import RealmSwift
import RxSwift
extension Realm {
func insertItems<T: Object>(items: [T]) -> Observable<Void> {
return Observable<Void>.create { observer in
do {
try self.write {
self.add(items, update: .modified)
}
observer.onNext(())
} catch {
observer.onError(error)
}
return Disposables.create()
}
}
func updateItems<T: Object>(items: [T]) -> Observable<Void> {
return Observable<Void>.create { observer in
do {
try self.write {
self.add(items, update: .modified)
}
observer.onNext(())
} catch {
observer.onError(error)
}
return Disposables.create()
}
}
func deleteItems<T: Object>(items: [T]) -> Observable<Void> {
return Observable<Void>.create { observer in
do {
try self.write {
self.delete(items)
}
observer.onNext(())
} catch {
observer.onError(error)
}
return Disposables.create()
}
}
func deleteAllItems<T: Object>(items: Results<T>) -> Observable<Void> {
return Observable<Void>.create { observer in
do {
try self.write {
self.delete(items)
}
observer.onNext(())
} catch {
observer.onError(error)
}
return Disposables.create()
}
}
func deleteAllItems<T: Object>(for type: T.Type) -> Observable<Void> {
return Observable<Void>.create { observer in
do {
try self.write {
self.delete(self.objects(type))
}
observer.onNext(())
} catch {
observer.onError(error)
}
return Disposables.create()
}
}
func getSingleElement<T: Object>(primaryKeyValue: String) -> Observable<T?> {
return Observable<T?>.create { observer in
observer.onNext(self.object(ofType: T.self, forPrimaryKey: primaryKeyValue))
return Disposables.create()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment