Skip to content

Commit

Permalink
Develop csv parser
Browse files Browse the repository at this point in the history
  • Loading branch information
kohkimakimoto committed Jun 9, 2014
1 parent 09fb1d6 commit 448f988
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 11 deletions.
14 changes: 14 additions & 0 deletions FMDBx.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
C25B3DF91936D46600174E72 /* FMXQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C25B3DF81936D46600174E72 /* FMXQueryTests.m */; };
C2935322194569F5003D2E6B /* FMXCsvTable.m in Sources */ = {isa = PBXBuildFile; fileRef = C2935321194569F5003D2E6B /* FMXCsvTable.m */; };
C293532419456A18003D2E6B /* FMXCsvTableTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C293532319456A18003D2E6B /* FMXCsvTableTests.m */; };
C29353271945839B003D2E6B /* users.csv in Resources */ = {isa = PBXBuildFile; fileRef = C29353261945839B003D2E6B /* users.csv */; };
C293532819458484003D2E6B /* users.csv in Resources */ = {isa = PBXBuildFile; fileRef = C29353261945839B003D2E6B /* users.csv */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -97,6 +99,7 @@
C2935320194569F5003D2E6B /* FMXCsvTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FMXCsvTable.h; sourceTree = "<group>"; };
C2935321194569F5003D2E6B /* FMXCsvTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FMXCsvTable.m; sourceTree = "<group>"; };
C293532319456A18003D2E6B /* FMXCsvTableTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FMXCsvTableTests.m; sourceTree = "<group>"; };
C29353261945839B003D2E6B /* users.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = users.csv; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -227,6 +230,7 @@
C254D2461931807C0040AE69 /* Classes */ = {
isa = PBXGroup;
children = (
C293532519458384003D2E6B /* CSV */,
C25B3DA719321B7000174E72 /* Models */,
C25B3DA01931905200174E72 /* Migration */,
C25B3DA3193219ED00174E72 /* FMXDatabaseConfigurationTests.m */,
Expand Down Expand Up @@ -257,6 +261,14 @@
name = Models;
sourceTree = "<group>";
};
C293532519458384003D2E6B /* CSV */ = {
isa = PBXGroup;
children = (
C29353261945839B003D2E6B /* users.csv */,
);
name = CSV;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -335,6 +347,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C293532819458484003D2E6B /* users.csv in Resources */,
C254D20E19317EDC0040AE69 /* InfoPlist.strings in Resources */,
C254D21619317EDC0040AE69 /* Images.xcassets in Resources */,
);
Expand All @@ -345,6 +358,7 @@
buildActionMask = 2147483647;
files = (
C254D22719317EDC0040AE69 /* InfoPlist.strings in Resources */,
C29353271945839B003D2E6B /* users.csv in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
10 changes: 5 additions & 5 deletions FMDBx/Classes/FMXCsvTable.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// FMXCsv.h
// FMXCsvTable.h
// FMDBx
//
// Created by KohkiMakimoto on 6/9/14.
Expand All @@ -10,12 +10,12 @@

@interface FMXCsvTable : NSObject

+ (void)foreachFileName:(NSString *)fileName process:(void (^)(NSArray *row))process;
+ (void)foreachFileName:(NSString *)fileName process:(void (^)(NSDictionary *row))process;

+ (void)foreachFileName:(NSString *)fileName columnSeparator:(NSString *)separator process:(void (^)(NSArray *row))process;
+ (void)foreachFileName:(NSString *)fileName columnSeparator:(NSString *)separator process:(void (^)(NSDictionary *row))process;

+ (void)foreachURL:(NSURL *)url process:(void (^)(NSArray *row))process;
+ (void)foreachURL:(NSURL *)url process:(void (^)(NSDictionary *row))process;

+ (void)foreachURL:(NSURL *)url columnSeparator:(NSString *)separator process:(void (^)(NSArray *row))process;
+ (void)foreachURL:(NSURL *)url columnSeparator:(NSString *)separator process:(void (^)(NSDictionary *row))process;

@end
76 changes: 71 additions & 5 deletions FMDBx/Classes/FMXCsvTable.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// FMXCsv.m
// FMXCsvTable.m
// FMDBx
//
// Created by KohkiMakimoto on 6/9/14.
Expand Down Expand Up @@ -37,31 +37,97 @@

#import "FMXCsvTable.h"

static NSCharacterSet *FMXCsvTableDigitCharacterSet = nil;
static NSArray *FMXCsvTableBooleanStrings = nil;

@implementation FMXCsvTable

+ (void)foreachFileName:(NSString *)fileName process:(void (^)(NSArray *))process
+ (void)foreachFileName:(NSString *)fileName process:(void (^)(NSDictionary *))process
{
[self foreachFileName:fileName columnSeparator:@"," process:process];
}

+ (void)foreachFileName:(NSString *)fileName columnSeparator:(NSString *)separator process:(void (^)(NSArray *))process
+ (void)foreachFileName:(NSString *)fileName columnSeparator:(NSString *)separator process:(void (^)(NSDictionary *))process
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:fileName ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
[self foreachURL:url columnSeparator:separator process:process];
}

+ (void)foreachURL:(NSURL *)url process:(void (^)(NSArray *))process
+ (void)foreachURL:(NSURL *)url process:(void (^)(NSDictionary *))process
{
[self foreachURL:url columnSeparator:@"," process:process];
}

+ (void)foreachURL:(NSURL *)url columnSeparator:(NSString *)separator process:(void (^)(NSArray *))process
+ (void)foreachURL:(NSURL *)url columnSeparator:(NSString *)separator process:(void (^)(NSDictionary *))process
{
NSString *csvString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
csvString = [csvString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];

NSArray *lines = [csvString componentsSeparatedByString:@"\n"];
NSArray *headers = [self headersFromLines:lines columnSeparator:separator];
NSArray *rows = [self rowsFromLines:lines headers:headers columnSeparator:separator];

for (NSDictionary *row in rows) {
process(row);
}
}

# pragma mark - private methods

+ (NSArray *)headersFromLines:(NSArray *)lines columnSeparator:(NSString *)separator
{
NSString *headerLine = lines.firstObject;
return [headerLine componentsSeparatedByString:separator];
}

+ (NSArray *)rowsFromLines:(NSArray *)lines headers:(NSArray *)headers columnSeparator:(NSString *)separator
{
NSMutableArray *rows = [NSMutableArray new];
for (NSString *line in lines) {
NSInteger lineNumber = [lines indexOfObject:line];
if (lineNumber == 0) {
continue;
}

NSArray *values = [line componentsSeparatedByString:separator];
NSMutableDictionary *row = [NSMutableDictionary new];
for (NSString *header in headers) {
NSUInteger index = [headers indexOfObject:header];
NSString *value = values[index];
if ([self isDigit:value]) {
row[header] = [NSNumber numberWithLongLong:value.longLongValue];
} else if ([self isBoolean:value]) {
row[header] = [NSNumber numberWithBool:value.boolValue];
} else {
row[header] = values[index];
}
}
[rows addObject:[NSDictionary dictionaryWithDictionary:row]];
}
return [NSArray arrayWithArray:rows];
}

+ (BOOL)isDigit:(NSString *)string
{
if (!FMXCsvTableDigitCharacterSet) {
FMXCsvTableDigitCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
}

NSScanner *scanner = [NSScanner localizedScannerWithString:string];
scanner.charactersToBeSkipped = NO;
[scanner scanCharactersFromSet:FMXCsvTableDigitCharacterSet intoString:NULL];
return scanner.isAtEnd;
}

+ (BOOL)isBoolean:(NSString *)string
{
if (!FMXCsvTableBooleanStrings) {
FMXCsvTableBooleanStrings = @[@"YES", @"NO", @"yes", @"no", @"TRUE", @"FALSE", @"true", @"false"];
}

return [FMXCsvTableBooleanStrings containsObject:string];
}

@end
15 changes: 14 additions & 1 deletion FMDBxTests/Classes/FMXCsvTableTests.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// FMXCsvTests.m
// FMXCsvTableTests.m
// FMDBx
//
// Created by KohkiMakimoto on 6/9/14.
Expand Down Expand Up @@ -32,6 +32,19 @@ - (void)tearDown

- (void)testForeachFileName
{
[FMXCsvTable foreachFileName:@"users.csv" columnSeparator:@"," process:^(NSDictionary *row){
NSNumber *idNumber = (NSNumber *)[row objectForKey:@"id"];
if ([idNumber isEqualToNumber:@(1)]) {
XCTAssertEqualObjects(@"Kohki Makimoto1", [row objectForKey:@"name"]);
XCTAssertEqualObjects(@(34), [row objectForKey:@"age"]);
}

if ([idNumber isEqualToNumber:@(2)]) {
XCTAssertEqualObjects(@"Kohki Makimoto2", [row objectForKey:@"name"]);
XCTAssertEqualObjects(@(35), [row objectForKey:@"age"]);
}

}];
}

- (void)testForeachURL
Expand Down
8 changes: 8 additions & 0 deletions FMDBxTests/Classes/users.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
id,name,age
1,Kohki Makimoto1,34
2,Kohki Makimoto2,35
3,Kohki Makimoto3,36
4,Kohki Makimoto4,37
5,Kohki Makimoto5,38
6,Kohki Makimoto6,39
7,Kohki Makimoto7,40

0 comments on commit 448f988

Please sign in to comment.