Skip to content

Commit

Permalink
Included more comments. Added a statement finalizer that throws errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
objecthub committed Apr 10, 2020
1 parent 8c2b97f commit 633fb2c
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 19 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Changelog

## 1.0.1 (2020-04-10)
- Fixed project setup
- Included more comments
- Added a statement finalizer that throws errors

## 1.0 (2020-04-04)
- Initial version
18 changes: 13 additions & 5 deletions SQLiteExpress.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
CC3625E724393037003A96DB /* SQLiteDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteDatabase.swift; sourceTree = "<group>"; };
CC3625EC24394912003A96DB /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
CC3625ED24394943003A96DB /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = "<group>"; };
CCC43D2A24394AFE005FFD1D /* SQLiteExpress_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLiteExpress_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CCC43D2A24394AFE005FFD1D /* SQLiteExpress iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = "SQLiteExpress iOS.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
CCC43D2C24394AFE005FFD1D /* SQLiteExpress_iOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLiteExpress_iOS.h; sourceTree = "<group>"; };
CCC43D2D24394AFE005FFD1D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -94,7 +94,7 @@
children = (
CC3625C724392F76003A96DB /* SQLiteExpress.framework */,
CC3625D024392F76003A96DB /* SQLiteExpressTests.xctest */,
CCC43D2A24394AFE005FFD1D /* SQLiteExpress_iOS.framework */,
CCC43D2A24394AFE005FFD1D /* SQLiteExpress iOS.framework */,
);
name = Products;
sourceTree = "<group>";
Expand Down Expand Up @@ -206,7 +206,7 @@
);
name = "SQLiteExpress iOS";
productName = "SQLiteExpress iOS";
productReference = CCC43D2A24394AFE005FFD1D /* SQLiteExpress_iOS.framework */;
productReference = CCC43D2A24394AFE005FFD1D /* SQLiteExpress iOS.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
Expand Down Expand Up @@ -440,6 +440,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = C72Z63N8M5;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -452,6 +453,7 @@
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = net.objecthub.SQLiteExpress;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
Expand All @@ -466,6 +468,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = C72Z63N8M5;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -478,6 +481,7 @@
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = net.objecthub.SQLiteExpress;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
Expand Down Expand Up @@ -527,6 +531,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = C72Z63N8M5;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -540,8 +545,9 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = net.objecthub.SQLiteExpress;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PRODUCT_NAME = "SQLiteExpress iOS";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
Expand All @@ -553,6 +559,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = C72Z63N8M5;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -566,8 +573,9 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = net.objecthub.SQLiteExpress;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PRODUCT_NAME = "SQLiteExpress iOS";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CCC43D2924394AFE005FFD1D"
BuildableName = "SQLiteExpress_iOS.framework"
BuildableName = "SQLiteExpress iOS.framework"
BlueprintName = "SQLiteExpress iOS"
ReferencedContainer = "container:SQLiteExpress.xcodeproj">
</BuildableReference>
Expand Down Expand Up @@ -75,7 +75,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CCC43D2924394AFE005FFD1D"
BuildableName = "SQLiteExpress_iOS.framework"
BuildableName = "SQLiteExpress iOS.framework"
BlueprintName = "SQLiteExpress iOS"
ReferencedContainer = "container:SQLiteExpress.xcodeproj">
</BuildableReference>
Expand Down
4 changes: 3 additions & 1 deletion Sources/SQLiteExpress iOS/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2020 Google LLC. All rights reserved.</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion Sources/SQLiteExpress/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
Expand Down
9 changes: 7 additions & 2 deletions Sources/SQLiteExpress/SQLiteError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import SQLite3

/// `SQLiteError` enumerates all errors that can be thrown by methods of the SQLiteExpress framework.
/// Both primary as well as extended result/error codes from SQLite are supported.
public enum SQLiteError: Error, Equatable {
public enum SQLiteError: Error, Hashable, CustomStringConvertible {
case ok
case error
case `internal`
Expand Down Expand Up @@ -320,9 +320,14 @@ public enum SQLiteError: Error, Equatable {
/// Returns a human readable error message for this `SQLiteError` object.
public var errorMessage: String {
if let cstr = sqlite3_errstr(self.errorCode) {
return String(cString: cstr)
return "\(String(cString: cstr)) \(self.errorCode)"
} else {
return "unknown sqlite3 error \(self.errorCode)"
}
}

/// Returns a description of this error as a string.
public var description: String {
return "SQLite3 error: \(self.errorMessage)"
}
}
46 changes: 45 additions & 1 deletion Sources/SQLiteExpress/SQLiteStatement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import Foundation
import SQLite3


/// `SQLiteStatement` represents a compiled SQL statement, typically generated by
/// `SQLiteDatabase.prepare`.
public class SQLiteStatement {

private static let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self)
Expand All @@ -46,7 +48,8 @@ public class SQLiteStatement {
sqlite3_finalize(self.stmt)
}

/// Returns true if the result is done
/// Executes this statement and returns `true` if the result is done. When `false` is returned,
/// `step()` can be called again to retrieve the next row of the result.
@discardableResult public func step() throws -> Bool {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -63,13 +66,16 @@ public class SQLiteStatement {
}
}

/// Resets this statement. This is typically called by clients when an error is encountered, or
/// `step()` is not invoked until all rows have been retrieved.
public func reset() {
guard self.stmt != nil else {
return
}
sqlite3_reset(self.stmt)
}

/// This will delete the statement, ignoring errors that are encountered.
public func finalize() {
guard self.stmt != nil else {
return
Expand All @@ -78,13 +84,31 @@ public class SQLiteStatement {
self.stmt = nil
}

/// This will delete the statement and throw errors that are encountered if the `throwingError`
/// argument is set to `true`.
public func finalize(throwingError: Bool) throws {
guard self.stmt != nil else {
return
}
let res = sqlite3_finalize(self.stmt)
if throwingError {
if res != SQLITE_OK && res != SQLITE_DONE {
throw SQLiteError(res)
}
}
self.stmt = nil
}

/// Returns the number of columns of the current result row. Columns are indexed started
/// with 0 (i.e. column 0 is the first column).
public var columnCount: Int {
guard self.stmt != nil else {
return 0
}
return Int(sqlite3_column_count(self.stmt))
}

/// Returns the name of column `col` of the current result row.
public func name(ofColumn col: Int) throws -> String? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -95,6 +119,7 @@ public class SQLiteStatement {
return String(cString: cstr)
}

/// Returns the database name of column `col` of the current result row.
public func databaseName(ofColumn col: Int) throws -> String? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -105,6 +130,7 @@ public class SQLiteStatement {
return String(cString: cstr)
}

/// Returns the table name of column `col` of the current result row.
public func tableName(ofColumn col: Int) throws -> String? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -115,6 +141,7 @@ public class SQLiteStatement {
return String(cString: cstr)
}

/// Returns the original name of column `col` of the current result row.
public func originalName(ofColumn col: Int) throws -> String? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -125,13 +152,15 @@ public class SQLiteStatement {
return String(cString: cstr)
}

/// Returns the type of column `col` of the current result row.
public func type(ofColumn col: Int) throws -> SQLiteType? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
}
return SQLiteType(rawValue: sqlite3_column_type(self.stmt, Int32(col)))
}

/// Returns the declared type of column `col` of the current result row.
public func declaredType(ofColumn col: Int) throws -> String? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -142,20 +171,23 @@ public class SQLiteStatement {
return String(cString: cstr)
}

/// Returns the integer value at column `col` of the current result row.
public func int(atColumn col: Int) throws -> Int64 {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
}
return sqlite3_column_int64(self.stmt, Int32(col))
}

/// Returns the floating-point value at column `col` of the current result row.
public func float(atColumn col: Int) throws -> Double {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
}
return sqlite3_column_double(self.stmt, Int32(col))
}

/// Returns the text value at column `col` of the current result row.
public func text(atColumn col: Int) throws -> String? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -166,6 +198,7 @@ public class SQLiteStatement {
return String(cString: cstr)
}

/// Returns the blob value at column `col` of the current result row.
public func blob(atColumn col: Int) throws -> Data? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -176,6 +209,7 @@ public class SQLiteStatement {
return Data(bytes: blob, count: Int(sqlite3_column_bytes(self.stmt, Int32(col))))
}

/// Returns the date value at column `col` of the current result row.
public func date(atColumn col: Int) throws -> Date? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -189,34 +223,39 @@ public class SQLiteStatement {
return date
}

/// Returns true, if column `col` of the current result row contains a _null_ value.
public func isNull(atColumn col: Int) throws -> Bool {
guard self.stmt != nil else {
throw SQLiteError.misuse
}
return sqlite3_column_type(self.stmt, Int32(col)) == SQLITE_NULL
}

/// Returns the number of parameters of this statement. Parameters are indexed starting at 1.
public var paramCount: Int {
guard self.stmt != nil else {
return 0
}
return Int(sqlite3_bind_parameter_count(self.stmt))
}

/// Returns the parameter index for the parameter with name `name`.
public func paramIndex(_ name: String) throws -> Int {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
}
return Int(sqlite3_bind_parameter_index(self.stmt, name.cString(using: .utf8)))
}

/// Returns the parameter name of the parameter at index `idx`.
public func paramName(_ idx: Int) throws -> String? {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
}
return String(cString: sqlite3_bind_parameter_name(self.stmt, Int32(idx)))
}

/// Binds the given integer value `x` to the parameter at index `idx`.
public func bind(integer x: Int64, toParam idx: Int) throws {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -227,6 +266,7 @@ public class SQLiteStatement {
}
}

/// Binds the given floating-point value `x` to the parameter at index `idx`.
public func bind(float x: Double, toParam idx: Int) throws {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -237,6 +277,7 @@ public class SQLiteStatement {
}
}

/// Binds the given string value `x` to the parameter at index `idx`.
public func bind(text x: String, toParam idx: Int) throws {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -251,6 +292,7 @@ public class SQLiteStatement {
}
}

/// Binds the given data value `x` to the parameter at index `idx`.
public func bind(blob x: Data, toParam idx: Int) throws {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -267,6 +309,7 @@ public class SQLiteStatement {
}
}

/// Binds the given date `x` to the parameter at index `idx`.
public func bind(date x: Date, toParam idx: Int) throws {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand All @@ -281,6 +324,7 @@ public class SQLiteStatement {
}
}

/// Binds _null_ to the parameter at index `idx`.
public func bindNull(toParam idx: Int) throws {
guard self.stmt != nil else {
throw SQLiteError(SQLITE_MISUSE)
Expand Down
Loading

0 comments on commit 633fb2c

Please sign in to comment.