Objective-LevelDB 2.1.5

Objective-LevelDB 2.1.5

测试已测试
Lang语言 Objective C++Objective C++
许可证 MIT
发布上次发布2016年1月

Mathieu D'Amours维护。



  • Michael Hoisie和Mathieu D'Amours

介绍

这是一个基于Google的LevelDB(一个由Google编写的快速嵌入式键值存储库)构建的Objective-C数据库库。

安装

到目前为止,将此库集成到项目中最容易的方法是使用CocoaPods

  1. 如果您还没有安装,请安装CocoaPods
  2. 在Podfile中添加以下行

    pod 'Objective-LevelDB'
    
  3. 运行pod install

  4. 制作一些令人惊艳的东西。

如何使用

在磁盘上创建/打开数据库文件

LevelDB *ldb = [LevelDB databaseInLibraryWithName:@"test.ldb"];
设置编码器/解码器块

默认情况下,您存储的任何对象都将使用NSKeyedArchiver/NSKeyedUnarchiver进行编码和解码。您可以通过提供encoderdecoder块来自定义此行为,如下所示:

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
}
类似于NSMutableDictionary的API
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();
}]

还有更多迭代方法,只需查看其头文件部分即可。

快照,类似于NSDictionary的API(不可变)

快照是实现数据库只读接口的界面,永久反映在它被创建时数据库的状态,即使之后数据库有所变化。

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];

所有可用方法都可以在其头文件中找到。

LevelDB选项
// 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许可下分发