Home

Awesome

#NyaruDB Build Status ###\(・ω・\)SAN値!(/・ω・)/ピンチ!

<a href="http://nyaruko.com/" target="_blank">這いよれ!ニャル子さんW</a>
2013年4月7日(日)深夜1:05~からテレビ東京ほかにて放送スタート!

MIT License

NyaruDB is a simple NoSQL database in Objective-C. It could be run on iOS and OS X.
It is a key-valu pair NoSQL database. You could search data by fields of the document.

##Feature ####More quickly than sqlite.

NyaruDB use memory cache, <a href="https://developer.apple.com/technologies/mac/core.html#grand-central" target="_blank">GCD</a> and binary tree to optimize performance.

NoSQL with SQL:  
NyaruDB: NSDictionary <-- NyaruDB --> File  
sqlite: NSDictionary <-- converter --> SQL <-- sqlite3 function --> File  
 NyaruDBsqlite
insert 1k documents11,000 ms <br/> 500 ms (async)36,500 ms
fetch 1k documents300 ms <br/> 50 ms (in cache)300 ms
search in 1k documents <br/> for 10 times12 ms40 ms
(this test is on iPhone4)
<br/> NyaruDB use GCD to write/read documents, **all accesses would be processed in a same dispatch**. Write: process with async GCD. Read: process with sync GCD. Writing documents to database will be processed in a async dispatch. So your code would not wait for writing documents. CPU will process the next command. If next command is reading documents from database, the command will be processed after writing done.

####Clean query syntax.

// where type == 1 order by update
NSArray *documents = [[[collection where:@"type" equal:@1] orderBy:@"update"] fetch];

##Installation ####git

$ git clone git://github.com/kelp404/NyaruDB.git

####<a href="http://cocoapods.org/" target="_blank">CocoadPods</a>:

add Podfile in your project path

platform :ios
pod 'NyaruDB'
$ pod install

##Management Tool ####<a href="https://github.com/kelp404/NyaruDB-Control" target="_blank">NyaruDB Control</a>
<img src='https://raw.github.com/kelp404/NyaruDB-Control/master/_images/screenshot00.png'/>


##Collection Collection is like Table of sql database.

##Index When you want to search data by a field, you should create a index.
If you want to search data by 'email', you should create a 'email' index before searching.

##Document Document is data in the collection.

There is a member named key in the document. Key is unique and datatype is NSString. If the document has no key when inserted, it will be automatically generated.


##Access Database ###Instance

####iOS [NyaruDB instance] returns a static NyaruDB instance, and database path is /your-app/Documents/NyaruDB.

NyaruDB *db = [NyaruDB instance];

####OS X [[NyaruDB alloc] initWithPath:@"/tmp/NyaruDB"].
NyaruDB will scan all documents in collections when [NyaruDB init], so do not call init too much.
In OS X, you should handle the static instance by yourself.

NyaruDB *db = [[NyaruDB alloc] initWithPath:@"/tmp/NyaruDB"];

###Create the collection

NyaruCollection *collectioin = [db collection:@"collectionName"];

###Create the index

NyaruCollection *collection = [db collection:@"collectionName"];
[collection createIndex:@"email"];
[collection createIndex:@"number"];
[collection createIndex:@"date"];

###Insert the document

If there is a document has the same 'key', it will be replace with the new document. (update document)

NyaruCollection *collection = [db collection:@"collectionName"];
NSDictionary *document = @{@"email": @"kelp@phate.org",
    @"name": @"Kelp",
    @"phone": @"0123456789",
    @"date": [NSDate date],
    @"text": @"(」・ω・)」うー!(/・ω・)/にゃー!",
    @"number": @100};
[collection put:document];

###Query

The field of the document which is key or index supports search.
key supports equal.
index supports equal, notEqual, less, lessEqual, greater, greaterEqual and like.

You could use and(Intersection) or or to append the query.

// search the document the 'key' is equal to 'IjkhMGIT752091136'
NyaruCollection *co = [db collection:@"collectionName"];
NSArray *documents = [[co where:@"key" equal:@"IjkhMGIT752091136"] fetch];
for (NSMutableDictionary *document in documents) {
    NSLog(@"%@", document);
}
// search documents the 'date' is greater than now, and sort by date with DESC
NyaruCollection *co = [db collection:@"collectionName"];
NSDate *date = [NSDate date];
NSArray *documents = [[[co where:@"date" greater:date] orderByDESC:@"date"] fetch];
for (NSMutableDictionary *document in documents) {
    NSLog(@"%@", document);
}
// search documents the 'date' is greater than now, and 'type' is equal to 2
// then sort by date with ASC
NyaruCollection *co = [db collection:@"collectionName"];
NSDate *date = [NSDate date];
NSArray *documents = [[[[co where:@"date" greater:date] and:@"type" equal:@2] orderBy:@"date"] fetch];
for (NSMutableDictionary *document in documents) {
    NSLog(@"%@", document);
}
// search documents 'type' == 1 or 'type' == 3
NyaruCollection *co = [db collection:@"collectionName"];
NSArray *documents = [[[co where:@"type" equal:@1] or:@"type" equal:@3] fetch];
for (NSMutableDictionary *document in documents) {
    NSLog(@"%@", document);
}
// count documents 'type' == 1
NyaruCollection *co = [db collection:@"collectionName"];
NSUInteger count = [[co where:@"type" equal:@1] count];
NSLog(@"%u", count);

###Delete documents

NyaruCollection *co = [db collection:@"collectionName"];
[co createIndex:@"number"];
[co put:@{@"number": @100}];
[co put:@{@"number": @200}];
[co put:@{@"number": @10}];
// remove by query
[[co where:@"number" equal:@10] remove];
// remove all
[[co all] remove];

###Sync & Async

put and remove will be run as async mode.
fetch and count will be run as sync mode. But all commands will be processed on a same dispatch.

After 1.4.1 NyaruDB has new messages about async fetch and count.
[NyaruQuery fetchAsync:(void (^)(NSArray *))handler]
[NyaruQuery countAsync:(void (^)(NSUInteger))handler]

If you wount to put documents as sync, you could use [NyaruCollection waitForWriting].

NyaruDB *db = [NyaruDB instance];
NyaruCollection *collection = [db collection:@"collection"];
NSDictionary *document = @{@"email": @"kelp@phate.org",
    @"name": @"Kelp",
    @"phone": @"0123456789",
    @"date": [NSDate date],
    @"text": @"(」・ω・)」",
    @"number": @100};
[collection put:document];
[collection waitForWriting];  // sync
// be Careful
NyaruDB *db = [NyaruDB instance];
NyaruCollection *collection = [db collection:@"collection"];
NSDictionary *document = @{@"email": @"kelp@phate.org",
    @"name": @"Kelp",
    @"phone": @"0123456789",
    @"date": [NSDate date],
    @"text": @"(」・ω・)」",
    @"number": @100};
for (NSUInteger index = 0; index < 1000; index++) {
    // put 1k documents
    [collection put:document];
}
// cpu will wait for documents write done.
// if this is main dispatch, it will be locked.
NSUInteger count = collection.count;
// you could try this
[collection countAsync:^(NSUInteger count) {
    // this block run in main dispatch
}];

##Class ###NyaruDB interface

#pragma mark - Instance
/**
 Get the shared instance for iOS.
 @return NyaruDB shared instance
 */
+ (id)instance;
/**
 Remove all database for iOS.
 if you init database error, maybe need to call this message.
 */
+ (void)reset;
/**
 Init NyaruDB for OS X.
 @param path Database files are in this path.
 @return NyaruDB instance
 */
- (id)initWithPath:(NSString *)path;
/**
 Close all file handles and collections for OS X.
 Before release instance you should invoke this method.
 */
- (void)close;
#pragma mark - Collection
- (NSArray *)collections;
- (NyaruCollection *)collection:(NSString *)name;
#pragma mark Remove
- (void)removeCollection:(NSString *)name;
- (void)removeAllCollections;

###NyaruCollection interface

#pragma mark - Index
- (NSArray *)allIndexes;
- (void)createIndex:(NSString *)indexName;
- (void)removeIndex:(NSString *)indexName;
- (void)removeAllindexes;
#pragma mark - Document
// put document
- (NSMutableDictionary *)put:(NSDictionary *)document;
// remove all documents (directly remove files)
- (void)removeAll;
// waiting for data writing
- (void)waitForWriting;
// clear cache
- (void)clearCache;
#pragma mark - Query
- (NyaruQuery *)all;
- (NyaruQuery *)where:(NSString *)indexName equal:(id)value;
- (NyaruQuery *)where:(NSString *)indexName notEqual:(id)value;
- (NyaruQuery *)where:(NSString *)indexName less:(id)value;
- (NyaruQuery *)where:(NSString *)indexName lessEqual:(id)value;
- (NyaruQuery *)where:(NSString *)indexName greater:(id)value;
- (NyaruQuery *)where:(NSString *)indexName greaterEqual:(id)value;
- (NyaruQuery *)where:(NSString *)indexName like:(NSString *)value;
#pragma mark - Count
- (NSUInteger)count;
- (void)countAsync:(void (^)(NSUInteger))handler;

###NyaruQuery interface

#pragma mark - Intersection
- (NyaruQuery *)and:(NSString *)indexName equal:(id)value;
- (NyaruQuery *)and:(NSString *)indexName notEqual:(id)value;
- (NyaruQuery *)and:(NSString *)indexName less:(id)value;
- (NyaruQuery *)and:(NSString *)indexName lessEqual:(id)value;
- (NyaruQuery *)and:(NSString *)indexName greater:(id)value;
- (NyaruQuery *)and:(NSString *)indexName greaterEqual:(id)value;
- (NyaruQuery *)and:(NSString *)indexName like:(NSString *)value;
#pragma mark - Union
- (NyaruQuery *)or:(NSString *)indexName equal:(id)value;
- (NyaruQuery *)or:(NSString *)indexName notEqual:(id)value;
- (NyaruQuery *)or:(NSString *)indexName less:(id)value;
- (NyaruQuery *)or:(NSString *)indexName lessEqual:(id)value;
- (NyaruQuery *)or:(NSString *)indexName greater:(id)value;
- (NyaruQuery *)or:(NSString *)indexName greaterEqual:(id)value;
- (NyaruQuery *)or:(NSString *)indexName like:(NSString *)value;
#pragma mark - Order By
- (NyaruQuery *)orderBy:(NSString *)indexName;
- (NyaruQuery *)orderByDESC:(NSString *)indexName;
#pragma mark - Count
- (NSUInteger)count;
- (void)countAsync:(void (^)(NSUInteger))handler;
#pragma mark - Fetch
- (NSArray *)fetch;
- (NSArray *)fetch:(NSUInteger)limit;
- (NSArray *)fetch:(NSUInteger)limit skip:(NSUInteger)skip;
- (NSMutableDictionary *)fetchFirst;
- (void)fetchAsync:(void (^)(NSArray *))handler;
- (void)fetch:(NSUInteger)limit async:(void (^)(NSArray *))handler;
- (void)fetch:(NSUInteger)limit skip:(NSUInteger)skip async:(void (^)(NSArray *))handler;
- (void)fetchFirstAsync:(void (^)(NSMutableDictionary *))handler;
#pragma mark - Remove
- (void)remove;

##Attention

##Thanks

##History