Permalink
Browse files

Adding hybrid storage class for XMPPRoom. Stores messages in a databa…

…se, and occupants in memory.
  • Loading branch information...
1 parent d2183cf commit a91f588264c8368106abc735ffdc2c9261e58957 @robbiehanson committed Feb 9, 2012
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>_XCCurrentVersionName</key>
+ <string>XMPPRoomHybrid.xcdatamodel</string>
+</dict>
+</plist>
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="878" systemVersion="11C74" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
+ <entity name="XMPPRoomMessageHybridCoreDataStorageObject" representedClassName="XMPPRoomMessageHybridCoreDataStorageObject" syncable="YES">
+ <attribute name="body" optional="YES" attributeType="String" indexed="YES" syncable="YES"/>
+ <attribute name="fromMe" attributeType="Boolean" defaultValueString="NO" syncable="YES"/>
+ <attribute name="jid" optional="YES" transient="YES" syncable="YES"/>
+ <attribute name="jidStr" attributeType="String" indexed="YES" syncable="YES"/>
+ <attribute name="localTimestamp" attributeType="Date" indexed="YES" syncable="YES"/>
+ <attribute name="message" optional="YES" transient="YES" syncable="YES"/>
+ <attribute name="messageStr" optional="YES" attributeType="String" syncable="YES"/>
+ <attribute name="nickname" optional="YES" attributeType="String" syncable="YES"/>
+ <attribute name="remoteTimestamp" optional="YES" attributeType="Date" indexed="YES" syncable="YES"/>
+ <attribute name="roomJID" optional="YES" transient="YES" syncable="YES"/>
+ <attribute name="roomJIDStr" attributeType="String" indexed="YES" syncable="YES"/>
+ <attribute name="streamBareJidStr" attributeType="String" indexed="YES" syncable="YES"/>
+ <attribute name="type" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
+ </entity>
+ <elements>
+ <element name="XMPPRoomMessageHybridCoreDataStorageObject" positionX="160" positionY="192" width="128" height="240"/>
+ </elements>
+</model>
@@ -0,0 +1,178 @@
+#import <Foundation/Foundation.h>
+#import <CoreData/CoreData.h>
+
+#import "XMPP.h"
+#import "XMPPRoom.h"
+#import "XMPPRoomMessageHybridCoreDataStorageObject.h"
+#import "XMPPRoomOccupantHybridMemoryStorageObject.h"
+#import "XMPPCoreDataStorage.h"
+
+/**
+ * This class is an example implementation of the XMPPRoomStorage protocol.
+ * It stores messages in a database using core data, and stores occupants in memory (as they are temporary).
+ *
+ * You are free to substitute your own storage class.
+**/
+
+@interface XMPPRoomHybridStorage : XMPPCoreDataStorage <XMPPRoomStorage>
+
+/**
+ * Convenience method to get an instance with the default database name.
+ *
+ * IMPORTANT:
+ * You are NOT required to use the sharedInstance.
+ *
+ * If your application makes extensive use of MUC, and you use a sharedInstance of this class,
+ * then all of your MUC rooms share the same database store. You might get better performance if you create
+ * multiple instances of this class instead (using different database filenames), as this way you can have
+ * concurrent writes to multiple databases.
+**/
++ (XMPPRoomHybridStorage *)sharedInstance;
+
+/* Inherited from XMPPCoreDataStorage
+ * Please see the XMPPCoreDataStorage header file for extensive documentation.
+
+- (id)initWithDatabaseFilename:(NSString *)databaseFileName;
+- (id)initWithInMemoryStore;
+
+@property (readonly) NSString *databaseFileName;
+
+@property (readwrite) NSUInteger saveThreshold;
+
+@property (readonly) NSManagedObjectModel *managedObjectModel;
+@property (readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
+
+*/
+
+/**
+ * You may choose to extend this class, and/or the message class for customized functionality.
+ * These properties allow for such customization.
+ *
+ * You must set your desired entity name, if different from default, before you begin using the storage class.
+**/
+@property (strong, readwrite) NSString * messageEntityName;
+
+/**
+ * You can optionally extend the XMPPRoomOccupantMemoryStorageObject class.
+ * Then just set the class here, and your subclass will automatically get used.
+ *
+ * You must set your desired class, if different from default, before you begin using the storage class.
+**/
+@property (assign, readwrite) Class occupantClass;
+
+/**
+ * It is likely you don't want the message history to persist forever.
+ * Doing so would allow the database to grow infinitely large over time.
+ *
+ * The maxMessageAge property provides a way to specify how old a message can get
+ * before it should get deleted from the database.
+ *
+ * The deleteInterval specifies how often to sweep for old messages.
+ * Since deleting is an expensive operation (disk io) it is done on a fixed interval.
+ *
+ * You can optionally disable the maxMessageAge by setting it to zero (or a negative value).
+ * If you disable the maxMessageAge then old messages are not deleted.
+ *
+ * You can optionally disable the deleteInterval by setting it to zero (or a negative value).
+ *
+ * The default maxAge is 7 days.
+ * The default deleteInterval is 5 minutes.
+**/
+@property (assign, readwrite) NSTimeInterval maxMessageAge;
+@property (assign, readwrite) NSTimeInterval deleteInterval;
+
+/**
+ * You may optionally prevent old message deletion for particular rooms.
+**/
+- (void)pauseOldMessageDeletionForRoom:(XMPPJID *)roomJID;
+- (void)resumeOldMessageDeletionForRoom:(XMPPJID *)roomJID;
+
+/**
+ * Convenience method to get the message entity description.
+ *
+ * @see messageEntityName
+**/
+- (NSEntityDescription *)messageEntity:(NSManagedObjectContext *)moc;
+
+/**
+ * Returns the timestamp of the most recent message stored in the database for the given room.
+ * This may be used when requesting the message history from the server,
+ * to prevent redownloading messages you already have.
+ *
+ * @param roomJID - The JID of the room (a bare JID)
+ *
+ * @param xmppStream - This class can support multiple concurrent xmppStreams.
+ * Optionally pass the xmppStream the room applies to.
+ * If you're using this claass with a single xmppStream, you can pass nil.
+ *
+ * @param moc - The managedObjectContext to use when doing the lookups.
+ * If non-nil, this should match the thread you're currently using.
+ * If nil, the operation is dispatch_sync'd onto the internal queue,
+ * and uses the internal managedObjectContext.
+ *
+ * The moc may optionally be nil strictly because this method does not return a NSManagedObject.
+**/
+- (NSDate *)mostRecentMessageTimestampForRoom:(XMPPJID *)roomJID
+ stream:(XMPPStream *)xmppStream
+ inContext:(NSManagedObjectContext *)moc;
+
+/**
+ * Returns the occupant for the given full jid.
+ *
+ * @param jid - The full jid of the room occupant (including resource).
+ * E.g. xmppDevelopers@conf.xmpp.org/robbiehanson
+ *
+ * @param xmppStream - This class can support multiple concurrent xmppStreams.
+ * Optionally pass the xmppStream the room applies to.
+ * If you're using this claass with a single xmppStream, you can pass nil.
+**/
+- (XMPPRoomOccupantHybridMemoryStorageObject *)occupantForJID:(XMPPJID *)jid stream:(XMPPStream *)xmppStream;
+
+/**
+ * Returns all occupants in the given room.
+ * Each occupant instance will be of kind XMPPRoomOccupantHybridMemoryStorageObject.
+ *
+ * @param roomJid - The JID of the room (a bare JID).
+ * E.g. xmppDevelopers@conf.xmpp.org
+ *
+ * @param xmppStream - This class can support multiple concurrent xmppStreams.
+ * Optionally pass the xmppStream the room applies to.
+ * If you're using this claass with a single xmppStream, you can pass nil.
+**/
+- (NSArray *)occupantsForRoom:(XMPPJID *)roomJid stream:(XMPPStream *)xmppStream;
+
+@end
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+@protocol XMPPRoomHybridStorageDelegate <NSObject>
+@optional
+
+//
+// XMPPRoomHybridStorage automatically uses the delegate(s) of its parent XMPPRoom.
+//
+
+/**
+ * Similar to XMPPRoomDelegate's xmppRoom:occupantDidJoin:withPresence: method.
+ * This method provides the delegate with the occupant storage instance.
+**/
+- (void)xmppRoomHybridStorage:(XMPPRoomHybridStorage *)sender
+ occupantDidJoin:(XMPPRoomOccupantHybridMemoryStorageObject *)occupant;
+
+/**
+ * Similar to XMPPRoomDelegate's xmppRoom:occupantDidLeave:withPresence: method.
+ * This method provides the delegate with the occupant storage instance.
+**/
+- (void)xmppRoomHybridStorage:(XMPPRoomHybridStorage *)sender
+ occupantDidLeave:(XMPPRoomOccupantHybridMemoryStorageObject *)occupant;
+
+/**
+ * Similar to XMPPRoomDelegate's xmppRoom:occupantDidUpdate:withPresence: method.
+ * This method provides the delegate with the occupant storage instance.
+**/
+- (void)xmppRoomHybridStorage:(XMPPRoomHybridStorage *)sender
+ occupantDidUpdate:(XMPPRoomOccupantHybridMemoryStorageObject *)occupant;
+
+@end
Oops, something went wrong.

0 comments on commit a91f588

Please sign in to comment.