Initial commit
This commit is contained in:
Generated
+19
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2012-2014 YTKKeyValueStore https://github.com/yuantiku
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Generated
+132
@@ -0,0 +1,132 @@
|
||||
|
||||
## 前言
|
||||
|
||||
还记得大学刚学数据库那会儿,天真地以为世界上所有的存储都需要用数据库来做。后来毕业后,正值NOSQL流行,那时我在网易参与了网易微博的开发,我们当时使用了有道自己做的“BigTable”— OMAP来存储微博数据,那个时候才发现,其实Key-Value这种简单的存储也能搞定微博这类不太简单的存储逻辑。
|
||||
|
||||
相比MYSQL,当数据量上千万后,NOSQL的优势体现出来了:对于海量数据,NOSQL在存取速度上没有任何影响,另外,天生的多备份和分布式,也说数据安全和扩容变得异常容易。
|
||||
|
||||
## iOS端的尝试
|
||||
|
||||
后来我从后台转做iOS端的开发,我就尝试了在iOS端直接使用Key-Value式的存储。经过在粉笔网、猿题库、小猿搜题三个客户端中的尝试后,我发现Key-Value式的存储不但完全能够满足大多数移动端开发的需求,而且非常适合移动端采用。主要原因是:移动端存储的数据量不会很大:
|
||||
|
||||
* 如果是单机的应用(例如效率工具Clear),用户自己一个人创建的数据最多也就上万条。
|
||||
* 如果是有服务端的应用(例如网易新闻,微博),那移动端通常不会保存全量的数据,每次会从服务器上获取数据,本地只是做一些内容的缓存而已,所以也不会有很大的数据量。
|
||||
|
||||
如果数据量不大的话,那么在iOS端使用最简单直接的Key-Value存储就能带来开发上的效率优势。它能保证:
|
||||
|
||||
1. Model层的代码编写简单,易于测试。
|
||||
2. 由于Value是JSON格式,所以在做Model字段更改时,易于扩展和兼容。
|
||||
|
||||
## 实现方案
|
||||
|
||||
在存储引擎上,2年前我直接选择了Sqlite当做存储引擎,相当于每个数据库表只有Key,Value两个字段。后来,随着LevelDB的流行,业界也有一些应用采用了LevelDB来做iOS端的Key-Value存储引擎,例如开源的[ViewFinder](https://github.com/viewfinderco/viewfinder)。
|
||||
|
||||
因为LevelDB本身并不是为移动端设计的,我担心它过于占用内存,我自己也没有看到业界有在移动端针对LevelDB做很详细的测试,连LevelDB的iOS端移植都不是官方做的。加上我自己写的基于Sqlite的Key-Value存储用着也没有什么问题,所以我也就一直没有更换成LevelDB。
|
||||
|
||||
## 开源
|
||||
|
||||
经过两年的使用和测试,我认为它非常好用,而且代码也非常简单,只有不到400行。所以现在开源分享给大家,这个项目叫`YTKKeyValueStore`,项目在[这里](https://github.com/yuantiku/YTKKeyValueStore)。以下是一个简单的使用示例:
|
||||
|
||||
```
|
||||
YTKKeyValueStore *store = [[YTKKeyValueStore alloc] initDBWithName:@"test.db"];
|
||||
NSString *tableName = @"user_table";
|
||||
[store createTableWithName:tableName];
|
||||
// 保存
|
||||
NSString *key = @"1";
|
||||
NSDictionary *user = @{@"id": @1, @"name": @"tangqiao", @"age": @30};
|
||||
[store putObject:user withId:key intoTable:tableName];
|
||||
// 查询
|
||||
NSDictionary *queryUser = [store getObjectById:key fromTable:tableName];
|
||||
NSLog(@"query data result: %@", queryUser);
|
||||
```
|
||||
|
||||
## 集成说明
|
||||
|
||||
使用本项目,你需要将开源代码中的`YTKKeyValueStore.h`和`YTKKeyValueStore.m`添加到你的工程中,并且在工程设置的`Link Binary With Libraries`中,增加`libsqlite3.dylib`,如下图所示:
|
||||
|
||||

|
||||
|
||||
由于时间关系,当前还未提供Cocoapods方式集成。
|
||||
|
||||
## 使用说明
|
||||
|
||||
所有的接口都封装在`YTKKeyValueStore`类中。以下是一些常用方法说明。
|
||||
|
||||
### 打开(或创建)数据库
|
||||
|
||||
通过`initDBWithName`方法,即可在程序的`Document`目录打开指定的数据库文件。如果该文件不存在,则会创建一个新的数据库。
|
||||
|
||||
```
|
||||
// 打开名为test.db的数据库,如果该文件不存在,则创新一个新的。
|
||||
YTKKeyValueStore *store = [[YTKKeyValueStore alloc] initDBWithName:@"test.db"];
|
||||
```
|
||||
|
||||
### 创建数据库表
|
||||
|
||||
通过`createTableWithName`方法,我们可以在打开的数据库中创建表,如果表名已经存在,则会忽略该操作。如下所示:
|
||||
|
||||
```
|
||||
YTKKeyValueStore *store = [[YTKKeyValueStore alloc] initDBWithName:@"test.db"];
|
||||
NSString *tableName = @"user_table";
|
||||
// 创建名为user_table的表,如果已存在,则忽略该操作
|
||||
[store createTableWithName:tableName];
|
||||
```
|
||||
|
||||
### 读写数据
|
||||
|
||||
`YTKKeyValueStore`类提供key-value的存储接口,存入的所有数据需要提供key以及其对应的value,读取的时候需要提供key来获得相应的value。
|
||||
|
||||
`YTKKeyValueStore`类支持的value类型包括:NSString, NSNumber, NSDictionary和NSArray,为此提供了以下接口:
|
||||
|
||||
```
|
||||
- (void)putString:(NSString *)string withId:(NSString *)stringId intoTable:(NSString *)tableName;
|
||||
- (void)putNumber:(NSNumber *)number withId:(NSString *)numberId intoTable:(NSString *)tableName;
|
||||
- (void)putObject:(id)object withId:(NSString *)objectId intoTable:(NSString *)tableName;
|
||||
```
|
||||
|
||||
与此对应,有以下value为NSString, NSNumber, NSDictionary和NSArray的读取接口:
|
||||
|
||||
```
|
||||
- (NSString *)getStringById:(NSString *)stringId fromTable:(NSString *)tableName;
|
||||
- (NSNumber *)getNumberById:(NSString *)numberId fromTable:(NSString *)tableName;
|
||||
- (id)getObjectById:(NSString *)objectId fromTable:(NSString *)tableName;
|
||||
```
|
||||
|
||||
### 删除数据接口
|
||||
|
||||
`YTKKeyValueStore`提供了以下接口用于删除数据。
|
||||
|
||||
```
|
||||
// 清除数据表中所有数据
|
||||
- (void)clearTable:(NSString *)tableName;
|
||||
|
||||
// 删除指定key的数据
|
||||
- (void)deleteObjectById:(NSString *)objectId fromTable:(NSString *)tableName;
|
||||
|
||||
// 批量删除一组key数组的数据
|
||||
- (void)deleteObjectsByIdArray:(NSArray *)objectIdArray fromTable:(NSString *)tableName;
|
||||
|
||||
// 批量删除所有带指定前缀的数据
|
||||
- (void)deleteObjectsByIdPrefix:(NSString *)objectIdPrefix fromTable:(NSString *)tableName;
|
||||
```
|
||||
|
||||
### 更多接口
|
||||
|
||||
`YTKKeyValueStore`还提供了以下接口来获取表示内部存储的key-value对象。
|
||||
|
||||
```
|
||||
// 获得指定key的数据
|
||||
- (YTKKeyValueItem *)getYTKKeyValueItemById:(NSString *)objectId fromTable:(NSString *)tableName;
|
||||
// 获得所有数据
|
||||
- (NSArray *)getAllItemsFromTable:(NSString *)tableName;
|
||||
```
|
||||
|
||||
由于`YTKKeyValueItem`类带有`createdTime`字段,可以获得该条数据的插入(或更新)时间,以便上层做复杂的处理(例如用来做缓存过期逻辑)。
|
||||
|
||||
## 协议
|
||||
|
||||
YTKKeyValueStore 被许可在 MIT 协议下使用。查阅 LICENSE 文件来获得更多信息。
|
||||
|
||||
## 其它
|
||||
|
||||
两年前写过不少测试用例,后来给弄丢了,所以现在开项项目中还没有测试用例。由于时间关系,更详细的使用说明稍后会更新到项目中。
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// YTKKeyValueStore.h
|
||||
// Ape
|
||||
//
|
||||
// Created by TangQiao on 12-11-6.
|
||||
// Copyright (c) 2012年 TangQiao. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface YTKKeyValueItem : NSObject
|
||||
|
||||
@property (strong, nonatomic) NSString *itemId;
|
||||
@property (strong, nonatomic) id itemObject;
|
||||
@property (strong, nonatomic) NSDate *createdTime;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface YTKKeyValueStore : NSObject
|
||||
|
||||
- (id)initDBWithName:(NSString *)dbName;
|
||||
|
||||
- (id)initWithDBWithPath:(NSString *)dbPath;
|
||||
|
||||
- (void)createTableWithName:(NSString *)tableName;
|
||||
|
||||
- (void)clearTable:(NSString *)tableName;
|
||||
|
||||
- (void)close;
|
||||
|
||||
///************************ Put&Get methods *****************************************
|
||||
|
||||
- (void)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;
|
||||
|
||||
- (NSString *)getStringById:(NSString *)stringId fromTable:(NSString *)tableName;
|
||||
|
||||
- (void)putNumber:(NSNumber *)number withId:(NSString *)numberId intoTable:(NSString *)tableName;
|
||||
|
||||
- (NSNumber *)getNumberById:(NSString *)numberId fromTable:(NSString *)tableName;
|
||||
|
||||
- (NSArray *)getAllItemsFromTable:(NSString *)tableName;
|
||||
|
||||
- (void)deleteObjectById:(NSString *)objectId fromTable:(NSString *)tableName;
|
||||
|
||||
- (void)deleteObjectsByIdArray:(NSArray *)objectIdArray fromTable:(NSString *)tableName;
|
||||
|
||||
- (void)deleteObjectsByIdPrefix:(NSString *)objectIdPrefix fromTable:(NSString *)tableName;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,316 @@
|
||||
//
|
||||
// YTKKeyValueStore.m
|
||||
// Ape
|
||||
//
|
||||
// Created by TangQiao on 12-11-6.
|
||||
// Copyright (c) 2012年 TangQiao. All rights reserved.
|
||||
//
|
||||
|
||||
#import "YTKKeyValueStore.h"
|
||||
#import "FMDatabase.h"
|
||||
#import "FMDatabaseQueue.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debugLog(...) NSLog(__VA_ARGS__)
|
||||
#define debugMethod() NSLog(@"%s", __func__)
|
||||
#define debugError() NSLog(@"Error at %s Line:%d", __func__, __LINE__)
|
||||
#else
|
||||
#define debugLog(...)
|
||||
#define debugMethod()
|
||||
#define debugError()
|
||||
#endif
|
||||
|
||||
#define PATH_OF_DOCUMENT [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
|
||||
|
||||
@implementation YTKKeyValueItem
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"id=%@, value=%@, timeStamp=%@", _itemId, _itemObject, _createdTime];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface YTKKeyValueStore()
|
||||
|
||||
@property (strong, nonatomic) FMDatabaseQueue * dbQueue;
|
||||
|
||||
@end
|
||||
|
||||
@implementation YTKKeyValueStore
|
||||
|
||||
static NSString *const DEFAULT_DB_NAME = @"database.sqlite";
|
||||
|
||||
static NSString *const CREATE_TABLE_SQL =
|
||||
@"CREATE TABLE IF NOT EXISTS %@ ( \
|
||||
id TEXT NOT NULL, \
|
||||
json TEXT NOT NULL, \
|
||||
createdTime TEXT NOT NULL, \
|
||||
PRIMARY KEY(id)) \
|
||||
";
|
||||
|
||||
static NSString *const UPDATE_ITEM_SQL = @"REPLACE INTO %@ (id, json, createdTime) values (?, ?, ?)";
|
||||
|
||||
static NSString *const QUERY_ITEM_SQL = @"SELECT json, createdTime from %@ where id = ? Limit 1";
|
||||
|
||||
static NSString *const SELECT_ALL_SQL = @"SELECT * from %@";
|
||||
|
||||
static NSString *const CLEAR_ALL_SQL = @"DELETE from %@";
|
||||
|
||||
static NSString *const DELETE_ITEM_SQL = @"DELETE from %@ where id = ?";
|
||||
|
||||
static NSString *const DELETE_ITEMS_SQL = @"DELETE from %@ where id in ( %@ )";
|
||||
|
||||
static NSString *const DELETE_ITEMS_WITH_PREFIX_SQL = @"DELETE from %@ where id like ? ";
|
||||
|
||||
+ (BOOL)checkTableName:(NSString *)tableName {
|
||||
if (tableName == nil || tableName.length == 0 || [tableName rangeOfString:@" "].location != NSNotFound) {
|
||||
debugLog(@"ERROR, table name: %@ format error.", tableName);
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
return [self initDBWithName:DEFAULT_DB_NAME];
|
||||
}
|
||||
|
||||
- (id)initDBWithName:(NSString *)dbName {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
NSString * dbPath = [PATH_OF_DOCUMENT stringByAppendingPathComponent:dbName];
|
||||
debugLog(@"dbPath = %@", dbPath);
|
||||
if (_dbQueue) {
|
||||
[self close];
|
||||
}
|
||||
_dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithDBWithPath:(NSString *)dbPath {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
debugLog(@"dbPath = %@", dbPath);
|
||||
if (_dbQueue) {
|
||||
[self close];
|
||||
}
|
||||
_dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)createTableWithName:(NSString *)tableName {
|
||||
if ([YTKKeyValueStore checkTableName:tableName] == NO) {
|
||||
return;
|
||||
}
|
||||
NSString * sql = [NSString stringWithFormat:CREATE_TABLE_SQL, tableName];
|
||||
__block BOOL result;
|
||||
[_dbQueue inDatabase:^(FMDatabase *db) {
|
||||
result = [db executeUpdate:sql];
|
||||
}];
|
||||
if (!result) {
|
||||
debugLog(@"ERROR, failed to create table: %@", tableName);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearTable:(NSString *)tableName {
|
||||
if ([YTKKeyValueStore checkTableName:tableName] == NO) {
|
||||
return;
|
||||
}
|
||||
NSString * sql = [NSString stringWithFormat:CLEAR_ALL_SQL, tableName];
|
||||
__block BOOL result;
|
||||
[_dbQueue inDatabase:^(FMDatabase *db) {
|
||||
result = [db executeUpdate:sql];
|
||||
}];
|
||||
if (!result) {
|
||||
debugLog(@"ERROR, failed to clear table: %@", tableName);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)putObject:(id)object withId:(NSString *)objectId intoTable:(NSString *)tableName {
|
||||
if ([YTKKeyValueStore checkTableName:tableName] == NO) {
|
||||
return;
|
||||
}
|
||||
NSError * error;
|
||||
NSData * data = [NSJSONSerialization dataWithJSONObject:object options:0 error:&error];
|
||||
if (error) {
|
||||
debugLog(@"ERROR, faild to get json data");
|
||||
return;
|
||||
}
|
||||
NSString * jsonString = [[NSString alloc] initWithData:data encoding:(NSUTF8StringEncoding)];
|
||||
NSDate * createdTime = [NSDate date];
|
||||
NSString * sql = [NSString stringWithFormat:UPDATE_ITEM_SQL, tableName];
|
||||
__block BOOL result;
|
||||
[_dbQueue inDatabase:^(FMDatabase *db) {
|
||||
result = [db executeUpdate:sql, objectId, jsonString, createdTime];
|
||||
}];
|
||||
if (!result) {
|
||||
debugLog(@"ERROR, failed to insert/replace into table: %@", tableName);
|
||||
}
|
||||
}
|
||||
|
||||
- (id)getObjectById:(NSString *)objectId fromTable:(NSString *)tableName {
|
||||
YTKKeyValueItem * item = [self getYTKKeyValueItemById:objectId fromTable:tableName];
|
||||
if (item) {
|
||||
return item.itemObject;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (YTKKeyValueItem *)getYTKKeyValueItemById:(NSString *)objectId fromTable:(NSString *)tableName {
|
||||
if ([YTKKeyValueStore checkTableName:tableName] == NO) {
|
||||
return nil;
|
||||
}
|
||||
NSString * sql = [NSString stringWithFormat:QUERY_ITEM_SQL, tableName];
|
||||
__block NSString * json = nil;
|
||||
__block NSDate * createdTime = nil;
|
||||
[_dbQueue inDatabase:^(FMDatabase *db) {
|
||||
FMResultSet * rs = [db executeQuery:sql, objectId];
|
||||
if ([rs next]) {
|
||||
json = [rs stringForColumn:@"json"];
|
||||
createdTime = [rs dateForColumn:@"createdTime"];
|
||||
}
|
||||
[rs close];
|
||||
}];
|
||||
if (json) {
|
||||
NSError * error;
|
||||
id result = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:(NSJSONReadingAllowFragments) error:&error];
|
||||
if (error) {
|
||||
debugLog(@"ERROR, faild to prase to json");
|
||||
return nil;
|
||||
}
|
||||
YTKKeyValueItem * item = [[YTKKeyValueItem alloc] init];
|
||||
item.itemId = objectId;
|
||||
item.itemObject = result;
|
||||
item.createdTime = createdTime;
|
||||
return item;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)putString:(NSString *)string withId:(NSString *)stringId intoTable:(NSString *)tableName {
|
||||
if (string == nil) {
|
||||
debugLog(@"error, string is nil");
|
||||
return;
|
||||
}
|
||||
[self putObject:@[string] withId:stringId intoTable:tableName];
|
||||
}
|
||||
|
||||
- (NSString *)getStringById:(NSString *)stringId fromTable:(NSString *)tableName {
|
||||
NSArray * array = [self getObjectById:stringId fromTable:tableName];
|
||||
if (array && [array isKindOfClass:[NSArray class]]) {
|
||||
return array[0];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)putNumber:(NSNumber *)number withId:(NSString *)numberId intoTable:(NSString *)tableName {
|
||||
if (number == nil) {
|
||||
debugLog(@"error, number is nil");
|
||||
return;
|
||||
}
|
||||
[self putObject:@[number] withId:numberId intoTable:tableName];
|
||||
}
|
||||
|
||||
- (NSNumber *)getNumberById:(NSString *)numberId fromTable:(NSString *)tableName {
|
||||
NSArray * array = [self getObjectById:numberId fromTable:tableName];
|
||||
if (array && [array isKindOfClass:[NSArray class]]) {
|
||||
return array[0];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *)getAllItemsFromTable:(NSString *)tableName {
|
||||
if ([YTKKeyValueStore checkTableName:tableName] == NO) {
|
||||
return nil;
|
||||
}
|
||||
NSString * sql = [NSString stringWithFormat:SELECT_ALL_SQL, tableName];
|
||||
__block NSMutableArray * result = [NSMutableArray array];
|
||||
[_dbQueue inDatabase:^(FMDatabase *db) {
|
||||
FMResultSet * rs = [db executeQuery:sql];
|
||||
while ([rs next]) {
|
||||
YTKKeyValueItem * item = [[YTKKeyValueItem alloc] init];
|
||||
item.itemId = [rs stringForColumn:@"id"];
|
||||
item.itemObject = [rs stringForColumn:@"json"];
|
||||
item.createdTime = [rs dateForColumn:@"createdTime"];
|
||||
[result addObject:item];
|
||||
}
|
||||
[rs close];
|
||||
}];
|
||||
// parse json string to object
|
||||
NSError * error;
|
||||
for (YTKKeyValueItem * item in result) {
|
||||
error = nil;
|
||||
id object = [NSJSONSerialization JSONObjectWithData:[item.itemObject dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:(NSJSONReadingAllowFragments) error:&error];
|
||||
if (error) {
|
||||
debugLog(@"ERROR, faild to prase to json.");
|
||||
} else {
|
||||
item.itemObject = object;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)deleteObjectById:(NSString *)objectId fromTable:(NSString *)tableName {
|
||||
if ([YTKKeyValueStore checkTableName:tableName] == NO) {
|
||||
return;
|
||||
}
|
||||
NSString * sql = [NSString stringWithFormat:DELETE_ITEM_SQL, tableName];
|
||||
__block BOOL result;
|
||||
[_dbQueue inDatabase:^(FMDatabase *db) {
|
||||
result = [db executeUpdate:sql, objectId];
|
||||
}];
|
||||
if (!result) {
|
||||
debugLog(@"ERROR, failed to delete item from table: %@", tableName);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)deleteObjectsByIdArray:(NSArray *)objectIdArray fromTable:(NSString *)tableName {
|
||||
if ([YTKKeyValueStore checkTableName:tableName] == NO) {
|
||||
return;
|
||||
}
|
||||
NSMutableString *stringBuilder = [NSMutableString string];
|
||||
for (id objectId in objectIdArray) {
|
||||
NSString *item = [NSString stringWithFormat:@" '%@' ", objectId];
|
||||
if (stringBuilder.length == 0) {
|
||||
[stringBuilder appendString:item];
|
||||
} else {
|
||||
[stringBuilder appendString:@","];
|
||||
[stringBuilder appendString:item];
|
||||
}
|
||||
}
|
||||
NSString *sql = [NSString stringWithFormat:DELETE_ITEMS_SQL, tableName, stringBuilder];
|
||||
__block BOOL result;
|
||||
[_dbQueue inDatabase:^(FMDatabase *db) {
|
||||
result = [db executeUpdate:sql];
|
||||
}];
|
||||
if (!result) {
|
||||
debugLog(@"ERROR, failed to delete items by ids from table: %@", tableName);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)deleteObjectsByIdPrefix:(NSString *)objectIdPrefix fromTable:(NSString *)tableName {
|
||||
if ([YTKKeyValueStore checkTableName:tableName] == NO) {
|
||||
return;
|
||||
}
|
||||
NSString *sql = [NSString stringWithFormat:DELETE_ITEMS_WITH_PREFIX_SQL, tableName];
|
||||
NSString *prefixArgument = [NSString stringWithFormat:@"%@%%", objectIdPrefix];
|
||||
__block BOOL result;
|
||||
[_dbQueue inDatabase:^(FMDatabase *db) {
|
||||
result = [db executeUpdate:sql, prefixArgument];
|
||||
}];
|
||||
if (!result) {
|
||||
debugLog(@"ERROR, failed to delete items by id prefix from table: %@", tableName);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
[_dbQueue close];
|
||||
_dbQueue = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user