diff --git a/YTKKeyValueStore.xcodeproj/project.pbxproj b/YTKKeyValueStore.xcodeproj/project.pbxproj index 653a894..c23e08f 100644 --- a/YTKKeyValueStore.xcodeproj/project.pbxproj +++ b/YTKKeyValueStore.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0C92970E1A090B7F0098DD16 /* YTKKeyValueManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C92970D1A090B7F0098DD16 /* YTKKeyValueManager.m */; }; 4597AE5A19DEDFB30028ECAC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4597AE5919DEDFB30028ECAC /* main.m */; }; 4597AE5D19DEDFB30028ECAC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4597AE5C19DEDFB30028ECAC /* AppDelegate.m */; }; 4597AE6019DEDFB30028ECAC /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4597AE5F19DEDFB30028ECAC /* ViewController.m */; }; @@ -34,6 +35,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0C92970C1A090B7F0098DD16 /* YTKKeyValueManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YTKKeyValueManager.h; sourceTree = ""; }; + 0C92970D1A090B7F0098DD16 /* YTKKeyValueManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YTKKeyValueManager.m; sourceTree = ""; }; 4597AE5419DEDFB30028ECAC /* YTKKeyValueStore.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YTKKeyValueStore.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4597AE5819DEDFB30028ECAC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4597AE5919DEDFB30028ECAC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -105,6 +108,8 @@ isa = PBXGroup; children = ( 4597AE9019DEE0D90028ECAC /* FMDB */, + 0C92970C1A090B7F0098DD16 /* YTKKeyValueManager.h */, + 0C92970D1A090B7F0098DD16 /* YTKKeyValueManager.m */, 4597AE7D19DEDFC80028ECAC /* YTKKeyValueStore.h */, 4597AE7E19DEDFC80028ECAC /* YTKKeyValueStore.m */, 4597AE5B19DEDFB30028ECAC /* AppDelegate.h */, @@ -265,6 +270,7 @@ files = ( 4597AE6019DEDFB30028ECAC /* ViewController.m in Sources */, 4597AE9F19DEE0D90028ECAC /* FMDatabaseQueue.m in Sources */, + 0C92970E1A090B7F0098DD16 /* YTKKeyValueManager.m in Sources */, 4597AE5D19DEDFB30028ECAC /* AppDelegate.m in Sources */, 4597AE7F19DEDFC80028ECAC /* YTKKeyValueStore.m in Sources */, 4597AE9C19DEE0D90028ECAC /* FMDatabase.m in Sources */, @@ -464,6 +470,7 @@ 4597AE7919DEDFB30028ECAC /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 4597AE7A19DEDFB30028ECAC /* Build configuration list for PBXNativeTarget "YTKKeyValueStoreTests" */ = { isa = XCConfigurationList; @@ -472,6 +479,7 @@ 4597AE7C19DEDFB30028ECAC /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/YTKKeyValueStore/AppDelegate.m b/YTKKeyValueStore/AppDelegate.m index 28041aa..de5a547 100644 --- a/YTKKeyValueStore/AppDelegate.m +++ b/YTKKeyValueStore/AppDelegate.m @@ -7,7 +7,7 @@ // #import "AppDelegate.h" -#import "YTKKeyValueStore.h" +#import "YTKKeyValueManager.h" @interface AppDelegate () @@ -19,15 +19,23 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Demo NSString *tableName = @"user_table"; - YTKKeyValueStore *store = [[YTKKeyValueStore alloc] initDBWithName:@"test.db"]; + NSString *msgTableName = @"msgTableName"; + YTKKeyValueStore *store = [YTKKeyValueManager getKeyValueStoreWithName:@"test.db"]; [store createTableWithName:tableName]; + [store createTableWithName:msgTableName]; + NSString *key = @"1"; NSDictionary *user = @{@"id": @1, @"name": @"tangqiao", @"age": @30}; - [store putObject:user withId:key intoTable:tableName]; + YTKKeyValueItem *item = [store putObject:user withId:key intoTable:tableName]; + [store putObject:item withId:key intoTable:msgTableName]; NSDictionary *queryUser = [store getObjectById:key fromTable:tableName]; NSLog(@"query data result: %@", queryUser); + YTKKeyValueItem *newItem = [store getObjectById:key fromTable:msgTableName]; + NSLog(@"query data result: %@", newItem); + + return YES; } diff --git a/YTKKeyValueStore/YTKKeyValueManager.h b/YTKKeyValueStore/YTKKeyValueManager.h new file mode 100644 index 0000000..2b54e48 --- /dev/null +++ b/YTKKeyValueStore/YTKKeyValueManager.h @@ -0,0 +1,18 @@ +// +// YTKKeyValueManager.h +// YTKKeyValueStore +// +// Created by Arthur on 14/11/4. +// Copyright (c) 2014年 TangQiao. All rights reserved. +// + +#import +#import "YTKKeyValueStore.h" + +@interface YTKKeyValueManager : NSObject + ++ (YTKKeyValueStore *)getKeyValueStoreWithName:(NSString *)name; ++ (YTKKeyValueStore *)getKeyValueStoreWithPath:(NSString *)path; ++ (void)closeKeyValueWith:(YTKKeyValueStore *)store; + +@end diff --git a/YTKKeyValueStore/YTKKeyValueManager.m b/YTKKeyValueStore/YTKKeyValueManager.m new file mode 100644 index 0000000..9ddd3df --- /dev/null +++ b/YTKKeyValueStore/YTKKeyValueManager.m @@ -0,0 +1,88 @@ +// +// YTKKeyValueManager.m +// YTKKeyValueStore +// +// Created by Arthur on 14/11/4. +// Copyright (c) 2014年 TangQiao. All rights reserved. +// + +#import "YTKKeyValueManager.h" + +@interface YTKKeyValueManager () + +@property (nonatomic, strong) NSMutableDictionary* stores; + +@end + +@implementation YTKKeyValueManager + ++ (YTKKeyValueManager*)defaultKeyValueManager { + static YTKKeyValueManager* manager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ manager = [[YTKKeyValueManager alloc] init]; }); + + return manager; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.stores = [[NSMutableDictionary alloc] init]; + } + + return self; +} + ++ (YTKKeyValueStore*)getKeyValueStoreWithName:(NSString*)name { + if (name.length == 0) { + return nil; + } + + NSString* path = [[NSSearchPathForDirectoriesInDomains( + NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] + stringByAppendingPathComponent:name]; + + return [YTKKeyValueManager getKeyValueStoreWithPath:path]; +} + ++ (YTKKeyValueStore*)getKeyValueStoreWithPath:(NSString*)path { + if (path.length == 0) { + return nil; + } + + YTKKeyValueManager* manager = [YTKKeyValueManager defaultKeyValueManager]; + + if ([manager.stores objectForKey:path]) { + return [manager.stores objectForKey:path]; + } else { + YTKKeyValueStore* store = + [[YTKKeyValueStore alloc] initWithDBWithPath:path]; + if (store) { + [manager.stores setObject:store forKey:path]; + return store; + } + } + + return nil; +} + ++ (void)closeKeyValueWith:(YTKKeyValueStore*)store { + YTKKeyValueManager* manager = [YTKKeyValueManager defaultKeyValueManager]; + NSString* deleteKey = nil; + + NSArray* keys = [manager.stores allKeys]; + for (NSString* key in keys) { + id object = [manager.stores objectForKey:key]; + if (object == store) { + deleteKey = key; + break; + } + } + + if (deleteKey) { + [store close]; + [manager.stores removeObjectForKey:deleteKey]; + } +} + +@end diff --git a/YTKKeyValueStore/YTKKeyValueStore.h b/YTKKeyValueStore/YTKKeyValueStore.h index 88e0e32..5bfb6f7 100644 --- a/YTKKeyValueStore/YTKKeyValueStore.h +++ b/YTKKeyValueStore/YTKKeyValueStore.h @@ -8,8 +8,15 @@ #import -@interface YTKKeyValueItem : NSObject +#define YTKKeyValueItem NSMutableDictionary +@interface NSMutableDictionary(YTKKeyValueStore) + +- (YTKKeyValueItem*)initKeyValueItemWithPath:(NSString *)path; +- (void)cleanObject; +- (void)loadObject; + +@property (strong, nonatomic) NSString *tableName; @property (strong, nonatomic) NSString *itemId; @property (strong, nonatomic) id itemObject; @property (strong, nonatomic) NSDate *createdTime; @@ -19,6 +26,8 @@ @interface YTKKeyValueStore : NSObject +@property (nonatomic, strong) NSString* dbPath; + - (id)initDBWithName:(NSString *)dbName; - (id)initWithDBWithPath:(NSString *)dbPath; @@ -31,17 +40,17 @@ ///************************ Put&Get methods ***************************************** -- (void)putObject:(id)object withId:(NSString *)objectId intoTable:(NSString *)tableName; +- (YTKKeyValueItem *)putObject:(id)object withId:(NSString *)objectId intoTable:(NSString *)tableName; - (id)getObjectById:(NSString *)objectId fromTable:(NSString *)tableName; - (YTKKeyValueItem *)getYTKKeyValueItemById:(NSString *)objectId fromTable:(NSString *)tableName; -- (void)putString:(NSString *)string withId:(NSString *)stringId intoTable:(NSString *)tableName; +- (YTKKeyValueItem *)putString:(NSString *)string withId:(NSString *)stringId intoTable:(NSString *)tableName; - (NSString *)getStringById:(NSString *)stringId fromTable:(NSString *)tableName; -- (void)putNumber:(NSNumber *)number withId:(NSString *)numberId intoTable:(NSString *)tableName; +- (YTKKeyValueItem *)putNumber:(NSNumber *)number withId:(NSString *)numberId intoTable:(NSString *)tableName; - (NSNumber *)getNumberById:(NSString *)numberId fromTable:(NSString *)tableName; diff --git a/YTKKeyValueStore/YTKKeyValueStore.m b/YTKKeyValueStore/YTKKeyValueStore.m index ea57d34..c19879b 100644 --- a/YTKKeyValueStore/YTKKeyValueStore.m +++ b/YTKKeyValueStore/YTKKeyValueStore.m @@ -9,6 +9,9 @@ #import "YTKKeyValueStore.h" #import "FMDatabase.h" #import "FMDatabaseQueue.h" +#import "YTKKeyValueManager.h" + +#define KeyValueItemType @"KeyValueItemType" #ifdef DEBUG #define debugLog(...) NSLog(__VA_ARGS__) @@ -22,10 +25,84 @@ #define PATH_OF_DOCUMENT [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] -@implementation YTKKeyValueItem +@implementation NSMutableDictionary(YTKKeyValueStore) + +- (YTKKeyValueItem*)initKeyValueItemWithPath:(NSString *)path +{ + self = [self init]; + if (self) { + [self setValue:path forKey:@"YTKKeyValueStorePath"]; + } + + return self; +} + +- (void)setTableName:(NSString *)tableName +{ + [self setValue:tableName forKey:@"YTKKeyValueStoreTableName"]; +} + +-(NSString *)tableName +{ + return [self objectForKey:@"YTKKeyValueStoreTableName"]; +} + +- (void)setCreatedTime:(NSDate *)createdTime +{ + if (createdTime) { + [self setValue:@(createdTime.timeIntervalSince1970) forKey:@"YTKKeyValueStoreCreatedTime"]; + } +} + +- (NSDate *)createdTime +{ + NSNumber *timeInterval = [self objectForKey:@"YTKKeyValueStoreCreatedTime"]; + if (timeInterval) { + return [NSDate dateWithTimeIntervalSince1970:[timeInterval floatValue]]; + + } else { + return nil; + } +} + +- (void)setItemId:(NSString *)itemId +{ + [self setValue:itemId forKey:@"YTKKeyValueStoreItemId"]; +} + +- (NSString *)itemId +{ + return [self objectForKey:@"YTKKeyValueStoreItemId"]; +} -- (NSString *)description { - return [NSString stringWithFormat:@"id=%@, value=%@, timeStamp=%@", _itemId, _itemObject, _createdTime]; +- (void)setItemObject:(id )itemObject +{ + [self setValue:itemObject forKey:@"YTKKeyValueStoreItemObject"]; +} + +- (id)itemObject +{ + return [self objectForKey:@"YTKKeyValueStoreItemObject"]; +} + +- (void)cleanObject +{ + [self removeObjectForKey:@"YTKKeyValueStoreItemObject"]; +} + +- (void)loadObject +{ + NSString * dbPath = [self objectForKey:@"YTKKeyValueStorePath"]; + if (dbPath) { + YTKKeyValueStore* store = [YTKKeyValueManager getKeyValueStoreWithPath:dbPath]; + if (store) { + YTKKeyValueItem*item = [store getYTKKeyValueItemById:self.itemId fromTable:self.tableName]; + self.itemObject = item.itemObject; + item = nil; + } + } else { + debugLog(@"dbPath is empty"); + } } @end @@ -82,6 +159,7 @@ - (id)initDBWithName:(NSString *)dbName { if (_dbQueue) { [self close]; } + _dbPath = dbPath; _dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath]; } return self; @@ -94,6 +172,7 @@ - (id)initWithDBWithPath:(NSString *)dbPath { if (_dbQueue) { [self close]; } + _dbPath = dbPath; _dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath]; } return self; @@ -127,15 +206,15 @@ - (void)clearTable:(NSString *)tableName { } } -- (void)putObject:(id)object withId:(NSString *)objectId intoTable:(NSString *)tableName { +- (YTKKeyValueItem *)putObject:(id)object withId:(NSString *)objectId intoTable:(NSString *)tableName { if ([YTKKeyValueStore checkTableName:tableName] == NO) { - return; + return nil; } NSError * error; NSData * data = [NSJSONSerialization dataWithJSONObject:object options:0 error:&error]; if (error) { debugLog(@"ERROR, faild to get json data"); - return; + return nil; } NSString * jsonString = [[NSString alloc] initWithData:data encoding:(NSUTF8StringEncoding)]; NSDate * createdTime = [NSDate date]; @@ -146,6 +225,15 @@ - (void)putObject:(id)object withId:(NSString *)objectId intoTable:(NSString *)t }]; if (!result) { debugLog(@"ERROR, failed to insert/replace into table: %@", tableName); + return nil; + } else { + YTKKeyValueItem *item = [[YTKKeyValueItem alloc] initKeyValueItemWithPath:self.dbPath]; + item.createdTime = createdTime; + item.tableName = tableName; + item.itemId = objectId; + item.itemObject = object; + + return item; } } @@ -181,22 +269,23 @@ - (YTKKeyValueItem *)getYTKKeyValueItemById:(NSString *)objectId fromTable:(NSSt debugLog(@"ERROR, faild to prase to json"); return nil; } - YTKKeyValueItem * item = [[YTKKeyValueItem alloc] init]; + YTKKeyValueItem * item = [[YTKKeyValueItem alloc] initKeyValueItemWithPath:self.dbPath]; item.itemId = objectId; item.itemObject = result; item.createdTime = createdTime; + item.tableName = tableName; return item; } else { return nil; } } -- (void)putString:(NSString *)string withId:(NSString *)stringId intoTable:(NSString *)tableName { +- (YTKKeyValueItem *)putString:(NSString *)string withId:(NSString *)stringId intoTable:(NSString *)tableName { if (string == nil) { debugLog(@"error, string is nil"); - return; + return nil; } - [self putObject:@[string] withId:stringId intoTable:tableName]; + return [self putObject:@[string] withId:stringId intoTable:tableName]; } - (NSString *)getStringById:(NSString *)stringId fromTable:(NSString *)tableName { @@ -207,12 +296,12 @@ - (NSString *)getStringById:(NSString *)stringId fromTable:(NSString *)tableName return nil; } -- (void)putNumber:(NSNumber *)number withId:(NSString *)numberId intoTable:(NSString *)tableName { +- (YTKKeyValueItem *)putNumber:(NSNumber *)number withId:(NSString *)numberId intoTable:(NSString *)tableName { if (number == nil) { debugLog(@"error, number is nil"); - return; + return nil; } - [self putObject:@[number] withId:numberId intoTable:tableName]; + return [self putObject:@[number] withId:numberId intoTable:tableName]; } - (NSNumber *)getNumberById:(NSString *)numberId fromTable:(NSString *)tableName { @@ -232,10 +321,11 @@ - (NSArray *)getAllItemsFromTable:(NSString *)tableName { [_dbQueue inDatabase:^(FMDatabase *db) { FMResultSet * rs = [db executeQuery:sql]; while ([rs next]) { - YTKKeyValueItem * item = [[YTKKeyValueItem alloc] init]; + YTKKeyValueItem * item = [[YTKKeyValueItem alloc] initKeyValueItemWithPath:self.dbPath]; item.itemId = [rs stringForColumn:@"id"]; item.itemObject = [rs stringForColumn:@"json"]; item.createdTime = [rs dateForColumn:@"createdTime"]; + item.tableName = tableName; [result addObject:item]; } [rs close];