Browse Source

Improve FMDBVersion

- Previously, `FMDBVersion` would break if any component exceeded 9.
- With this change, it doesn't break until any component exceeds 15, at which point it will max out at 0xf for that component and log an error.
- Added documentation suggesting FMDBUserVersion with NSNumericSearch option.
- Added unit tests for proper version number checking.
- While unit testing, I noticed that `testBoolInsert` was attempting `[NSNumber numberWithBool:12]`, which is not valid. Replaced with `YES`.
Robert Ryan 5 years ago
parent
commit
f4ddeb5239

+ 13 - 4
Tests/FMDatabaseTests.m

@@ -256,7 +256,7 @@ - (void)testCaseSensitiveResultDictionary
 {
     // case sensitive result dictionary test
     [self.db executeUpdate:@"create table cs (aRowName integer, bRowName text)"];
-    [self.db executeUpdate:@"insert into cs (aRowName, bRowName) values (?, ?)", [NSNumber numberWithBool:1], @"hello"];
+    [self.db executeUpdate:@"insert into cs (aRowName, bRowName) values (?, ?)", [NSNumber numberWithInt:1], @"hello"];
 
     XCTAssertFalse([self.db hadError], @"Shouldn't have any errors");
 
@@ -278,13 +278,12 @@ - (void)testCaseSensitiveResultDictionary
 - (void)testBoolInsert
 {
     [self.db executeUpdate:@"create table btest (aRowName integer)"];
-    [self.db executeUpdate:@"insert into btest (aRowName) values (?)", [NSNumber numberWithBool:12]];
+    [self.db executeUpdate:@"insert into btest (aRowName) values (?)", [NSNumber numberWithBool:YES]];
     
     XCTAssertFalse([self.db hadError], @"Shouldn't have any errors");
     
     FMResultSet *rs = [self.db executeQuery:@"select * from btest"];
     while ([rs next]) {
-        
         XCTAssertTrue([rs boolForColumnIndex:0], @"first column should be true.");
         XCTAssertTrue([rs intForColumnIndex:0] == 1, @"first column should be equal to 1 - it was %d.", [rs intForColumnIndex:0]);
     }
@@ -1125,7 +1124,17 @@ - (void)createCustomFunctions {
 }
 
 - (void)testVersionNumber {
-    XCTAssertTrue([FMDatabase FMDBVersion] == 0x0275); // this is going to break everytime we bump it.
+    XCTAssertEqual([FMDatabase FMDBVersion], 0x0276); // this is going to break everytime we bump it.
+}
+
+- (void)testVersionStringAboveRequired {
+    NSComparisonResult result = [[FMDatabase FMDBUserVersion] compare:@"1.100.42" options:NSNumericSearch];
+    XCTAssertEqual(result, NSOrderedDescending);
+}
+
+- (void)testVersionStringBelowRequired {
+    NSComparisonResult result = [[FMDatabase FMDBUserVersion] compare:@"10.0.42" options:NSNumericSearch];
+    XCTAssertEqual(result, NSOrderedAscending);
 }
 
 - (void)testExecuteStatements {

+ 3 - 1
fmdb.xcodeproj/project.pbxproj

@@ -606,7 +606,7 @@
 		08FB7793FE84155DC02AAC07 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 1000;
+				LastUpgradeCheck = 1140;
 				TargetAttributes = {
 					83C73EFD1C326AB000FFC730 = {
 						CreatedOnToolsVersion = 7.2;
@@ -805,6 +805,7 @@
 				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+				CODE_SIGN_IDENTITY = "-";
 				COPY_PHASE_STRIP = NO;
 				GCC_DYNAMIC_NO_PIC = NO;
 				GCC_OPTIMIZATION_LEVEL = 0;
@@ -828,6 +829,7 @@
 				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+				CODE_SIGN_IDENTITY = "-";
 				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
 				GCC_MODEL_TUNING = G5;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;

+ 1 - 5
fmdb.xcodeproj/xcshareddata/xcschemes/FMDB MacOS.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1000"
+   LastUpgradeVersion = "1140"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
@@ -29,8 +29,6 @@
       shouldUseLaunchSchemeArgsEnv = "YES">
       <Testables>
       </Testables>
-      <AdditionalOptions>
-      </AdditionalOptions>
    </TestAction>
    <LaunchAction
       buildConfiguration = "Debug"
@@ -51,8 +49,6 @@
             ReferencedContainer = "container:fmdb.xcodeproj">
          </BuildableReference>
       </MacroExpansion>
-      <AdditionalOptions>
-      </AdditionalOptions>
    </LaunchAction>
    <ProfileAction
       buildConfiguration = "Release"

+ 1 - 5
fmdb.xcodeproj/xcshareddata/xcschemes/FMDB iOS.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1000"
+   LastUpgradeVersion = "1140"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
@@ -29,8 +29,6 @@
       shouldUseLaunchSchemeArgsEnv = "YES">
       <Testables>
       </Testables>
-      <AdditionalOptions>
-      </AdditionalOptions>
    </TestAction>
    <LaunchAction
       buildConfiguration = "Debug"
@@ -51,8 +49,6 @@
             ReferencedContainer = "container:fmdb.xcodeproj">
          </BuildableReference>
       </MacroExpansion>
-      <AdditionalOptions>
-      </AdditionalOptions>
    </LaunchAction>
    <ProfileAction
       buildConfiguration = "Release"

+ 3 - 7
fmdb.xcodeproj/xcshareddata/xcschemes/FMDB watchOS.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1000"
+   LastUpgradeVersion = "1140"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
@@ -27,8 +27,6 @@
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       shouldUseLaunchSchemeArgsEnv = "YES">
-      <Testables>
-      </Testables>
       <MacroExpansion>
          <BuildableReference
             BuildableIdentifier = "primary"
@@ -38,8 +36,8 @@
             ReferencedContainer = "container:fmdb.xcodeproj">
          </BuildableReference>
       </MacroExpansion>
-      <AdditionalOptions>
-      </AdditionalOptions>
+      <Testables>
+      </Testables>
    </TestAction>
    <LaunchAction
       buildConfiguration = "Debug"
@@ -60,8 +58,6 @@
             ReferencedContainer = "container:fmdb.xcodeproj">
          </BuildableReference>
       </MacroExpansion>
-      <AdditionalOptions>
-      </AdditionalOptions>
    </LaunchAction>
    <ProfileAction
       buildConfiguration = "Release"

+ 27 - 1
src/fmdb/FMDatabase.h

@@ -1085,11 +1085,37 @@ typedef NS_ENUM(int, FMDBCheckpointMode) {
 
 + (NSString*)sqliteLibVersion;
 
+/**
+ The FMDB version number as a string in the form of `"2.7.7"`.
+
+ If you want to compare version number strings, you can use NSNumericSearch option:
+
+ @code
+ NSComparisonResult result = [[FMDatabase FMDBUserVersion] compare:@"2.11.0" options:NSNumericSearch];
+ @endcode
+
+ @returns The version number string.
+ */
 
 + (NSString*)FMDBUserVersion;
 
-+ (SInt32)FMDBVersion;
+/** The FMDB version
 
+ This returns the FMDB as hexadecimal value, e.g., 0x0243 for version 2.4.3.
+
+ @warning This routine will not work if any component of the version number exceeds 15.
+       For example, if it is version 2.17.3, this will max out at 0x2f3.
+       For this reason, we would recommend using `FMDBUserVersion` and with `NSNumericSearch` option, e.g.
+
+ @code
+ NSComparisonResult result = [[FMDatabase FMDBUserVersion] compare:@"2.11.0" options:NSNumericSearch];
+ @endcode
+
+ @returns The version number in hexadecimal, e.g., 0x0243 for version 2.4.3. If any component exceeds what can be
+       can be represented in four bits, we'll max it out at 0xf.
+ */
+
++ (SInt32)FMDBVersion;
 
 ///------------------------
 /// @name Make SQL function

+ 11 - 11
src/fmdb/FMDatabase.m

@@ -102,10 +102,6 @@ + (NSString*)FMDBUserVersion {
     return @"2.7.6";
 }
 
-// returns 0x0240 for version 2.4.  This makes it super easy to do things like:
-// /* need to make sure to do X with FMDB version 2.4 or later */
-// if ([FMDatabase FMDBVersion] >= 0x0240) { … }
-
 + (SInt32)FMDBVersion {
     
     // we go through these hoops so that we only have to change the version number in a single spot.
@@ -115,15 +111,19 @@ + (SInt32)FMDBVersion {
     dispatch_once(&once, ^{
         NSString *prodVersion = [self FMDBUserVersion];
         
-        if ([[prodVersion componentsSeparatedByString:@"."] count] < 3) {
+        while ([[prodVersion componentsSeparatedByString:@"."] count] < 3) {
             prodVersion = [prodVersion stringByAppendingString:@".0"];
         }
-        
-        NSString *junk = [prodVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
-        
-        char *e = nil;
-        FMDBVersionVal = (int) strtoul([junk UTF8String], &e, 16);
-        
+
+        NSArray *components = [prodVersion componentsSeparatedByString:@"."];
+        for (NSInteger i = 0; i < 3; i++) {
+            SInt32 component = [components[i] intValue];
+            if (component > 15) {
+                NSLog(@"FMDBVersion is invalid: Please use FMDBUserVersion instead.");
+                component = 15;
+            }
+            FMDBVersionVal = FMDBVersionVal << 4 | component;
+        }
     });
     
     return FMDBVersionVal;