测试已测试 | ✓ |
Lang语言 | Objective C++Objective C++ |
许可证 | MIT |
发布上次发布 | 2016年1月 |
由Mathieu D'Amours维护。
这是一个基于Google的LevelDB(一个由Google编写的快速嵌入式键值存储库)构建的Objective-C数据库库。
到目前为止,将此库集成到项目中最容易的方法是使用CocoaPods。
在Podfile中添加以下行
pod 'Objective-LevelDB'
运行pod install
LevelDB *ldb = [LevelDB databaseInLibraryWithName:@"test.ldb"];
默认情况下,您存储的任何对象都将使用NSKeyedArchiver
/NSKeyedUnarchiver
进行编码和解码。您可以通过提供encoder
和decoder
块来自定义此行为,如下所示:
ldb.encoder = ^ NSData * (LevelDBKey *key, id object) {
// return some data, given an object
}
ldb.decoder = ^ id (LevelDBKey *key, NSData * data) {
// return an object, given some data
}
ldb[@"string_test"] = @"laval"; // same as:
[ldb setObject:@"laval" forKey:@"string_test"];
NSLog(@"String Value: %@", ldb[@"string_test"]); // same as:
NSLog(@"String Value: %@", [ldb objectForKey:@"string_test"]);
[ldb setObject:@{@"key1" : @"val1", @"key2" : @"val2"} forKey:@"dict_test"];
NSLog(@"Dictionary Value: %@", [ldb objectForKey:@"dict_test"]);
所有可用方法都可以在其头文件中找到(有文档说明)。
[ldb enumerateKeysAndObjectsUsingBlock:^(LevelDBKey *key, id value, BOOL *stop) {
// This step is necessary since the key could be a string or raw data (use NSDataFromLevelDBKey in that case)
NSString *keyString = NSStringFromLevelDBKey(key); // Assumes UTF-8 encoding
// Do something clever
}];
// Enumerate with options
[ldb enumerateKeysAndObjectsBackward:TRUE
lazily:TRUE // Block below will have a block(void) instead of id argument for value
startingAtKey:someKey // Start iteration there (NSString or NSData)
filteredByPredicate:predicate // Only iterate over values matching NSPredicate
andPrefix:prefix // Only iterate over keys prefixed with something
usingBlock:^(LevelDBKey *key, void(^valueGetter)(void), BOOL *stop) {
NSString *keyString = NSStringFromLevelDBKey(key);
// If we had wanted the value directly instead of a valueGetter block, we would've set the
// above 'lazily' argument to FALSE
id value = valueGetter();
}]
还有更多迭代方法,只需查看其头文件部分即可。
快照是实现数据库只读接口的界面,永久反映在它被创建时数据库的状态,即使之后数据库有所变化。
LDBSnapshot *snap = [ldb newSnapshot]; // You get ownership of this variable, so in non-ARC projects,
// you'll need to release/autorelease it eventually
[ldb removeObjectForKey:@"string_test"];
// The result of these calls will reflect the state of ldb when the snapshot was taken
NSLog(@"String Value: %@", [snap objectForKey:@"string_test"]);
NSLog(@"Dictionary Value: %@", [ldb objectForKey:@"dict_test"]);
所有可用方法都可以在其头文件中找到。
写入批次是对LevelDB
数据库的可变代理,累积更新而不应用它们,直到您使用-[LDBWritebatch apply]
应用它们。
LDBWritebatch *wb = [ldb newWritebatch];
[wb setObject:@{ @"foo" : @"bar" } forKey: @"another_test"];
[wb removeObjectForKey:@"dict_test"];
// Those changes aren't yet applied to ldb
// To apply them in batch,
[wb apply];
所有可用方法都可以在其头文件中找到。
// The following values are the default
LevelDBOptions options = [LevelDB makeOptions];
options.createIfMissing = true;
options.errorIfExists = false;
options.paranoidCheck = false;
options.compression = true;
options.filterPolicy = 0; // Size in bits per key, allocated for a bloom filter, used in testing presence of key
options.cacheSize = 0; // Size in bytes, allocated for a LRU cache used for speeding up lookups
// Then, you can provide it when initializing a db instance.
LevelDB *ldb = [LevelDB databaseInLibraryWithName:@"test.ldb" andOptions:options];
db.safe = true; // Make sure to data was actually written to disk before returning from write operations.
[ldb setObject:@"laval" forKey:@"string_test"];
[ldb setObject:[NSDictionary dictionaryWithObjectsAndKeys:@"val1", @"key1", @"val2", @"key2", nil] forKey:@"dict_test"];
db.safe = false; // Switch back to default
db.useCache = false; // Do not use DB cache when reading data (default to true);
如谷歌的文档所述,从leveldb实例更新和读取不需要外部同步即可实现线程安全。写入批处理需要,我们已经处理了,通过在一个串行分发队列中将每个LDBWritebatch
隔离,并使每个请求异步分发到它。所以你在任何地方使用它,它都会正常工作。
然而,如果你使用类似JSONKit的库将数据编码为JSON存储到数据库中,并且足够聪明地预先分配一个用于所有数据解码的JSONDecoder
实例,请注意这个特定对象是不线程安全的,你需要手动处理。
如果你想运行测试,你需要XCode 5,因为测试套件使用的是新的XCTest。
克隆此仓库并进入其中,
./setup-test.sh
cd Tests && open Objective-LevelDB.xcworkspace
目前,所有测试都设置为与iOS测试套件一起工作。
在MIT许可下分发