Skip to content

Commit 773ac26

Browse files
committed
Reactivate #416
1 parent a4c1d1d commit 773ac26

File tree

7 files changed

+55
-22
lines changed

7 files changed

+55
-22
lines changed

Sources/SQLite/Core/Blob.swift

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,55 @@
2121
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2222
// THE SOFTWARE.
2323
//
24+
import Foundation
2425

25-
public struct Blob {
26+
public final class Blob {
2627

27-
public let bytes: [UInt8]
28+
public let data: NSData
2829

29-
public init(bytes: [UInt8]) {
30-
self.bytes = bytes
30+
public var bytes: UnsafeRawPointer {
31+
data.bytes
3132
}
3233

33-
public init(bytes: UnsafeRawPointer, length: Int) {
34-
let i8bufptr = UnsafeBufferPointer(start: bytes.assumingMemoryBound(to: UInt8.self), count: length)
35-
self.init(bytes: [UInt8](i8bufptr))
34+
public var length: Int {
35+
data.count
3636
}
3737

38-
public func toHex() -> String {
39-
bytes.map {
40-
($0 < 16 ? "0" : "") + String($0, radix: 16, uppercase: false)
41-
}.joined(separator: "")
38+
public convenience init(bytes: [UInt8]) {
39+
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bytes.count)
40+
for idx in 0..<bytes.count {
41+
buffer.advanced(by: idx).pointee = bytes[idx]
42+
}
43+
44+
let data = NSData(
45+
bytesNoCopy: UnsafeMutableRawPointer(buffer),
46+
length: bytes.count,
47+
freeWhenDone: true
48+
)
49+
self.init(data: data)
4250
}
4351

52+
public convenience init(bytes: UnsafeRawPointer, length: Int) {
53+
self.init(data: NSData(bytes: bytes, length: length))
54+
}
55+
56+
public init(data: NSData) {
57+
self.data = data
58+
}
59+
60+
public func toHex() -> String {
61+
let bytes = bytes.assumingMemoryBound(to: UInt8.self)
62+
63+
var hex = ""
64+
for idx in 0..<length {
65+
let byte = bytes.advanced(by: idx).pointee
66+
if byte < 16 {
67+
hex += "0"
68+
}
69+
hex += String(byte, radix: 16, uppercase: false)
70+
}
71+
return hex
72+
}
4473
}
4574

4675
extension Blob: CustomStringConvertible {

Sources/SQLite/Core/Connection.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ extension Context {
741741
func set(result: Binding?) {
742742
switch result {
743743
case let blob as Blob:
744-
sqlite3_result_blob(self, blob.bytes, Int32(blob.bytes.count), nil)
744+
sqlite3_result_blob(self, blob.bytes, Int32(blob.length), nil)
745745
case let double as Double:
746746
sqlite3_result_double(self, double)
747747
case let int as Int64:

Sources/SQLite/Core/Statement.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public final class Statement {
103103
if value == nil {
104104
sqlite3_bind_null(handle, Int32(idx))
105105
} else if let value = value as? Blob {
106-
sqlite3_bind_blob(handle, Int32(idx), value.bytes, Int32(value.bytes.count), SQLITE_TRANSIENT)
106+
sqlite3_bind_blob(handle, Int32(idx), value.bytes, Int32(value.length), SQLITE_TRANSIENT)
107107
} else if let value = value as? Double {
108108
sqlite3_bind_double(handle, Int32(idx), value)
109109
} else if let value = value as? Int64 {

Sources/SQLite/Foundation.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,11 @@ extension Data: Value {
3131
}
3232

3333
public static func fromDatatypeValue(_ dataValue: Blob) -> Data {
34-
Data(dataValue.bytes)
34+
dataValue.data as Data
3535
}
3636

3737
public var datatypeValue: Blob {
38-
withUnsafeBytes { (pointer: UnsafeRawBufferPointer) -> Blob in
39-
Blob(bytes: pointer.baseAddress!, length: count)
40-
}
38+
Blob(data: self as NSData)
4139
}
4240

4341
}

Tests/SQLiteTests/Core/BlobTests.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ class BlobTests: XCTestCase {
1111

1212
func test_init_array() {
1313
let blob = Blob(bytes: [42, 42, 42])
14-
XCTAssertEqual(blob.bytes, [42, 42, 42])
14+
XCTAssertEqual(blob.byteArray, [42, 42, 42])
1515
}
1616

1717
func test_init_unsafeRawPointer() {
1818
let pointer = UnsafeMutablePointer<UInt8>.allocate(capacity: 3)
1919
pointer.initialize(repeating: 42, count: 3)
2020
let blob = Blob(bytes: pointer, length: 3)
21-
XCTAssertEqual(blob.bytes, [42, 42, 42])
21+
XCTAssertEqual(blob.byteArray, [42, 42, 42])
22+
}
23+
}
24+
25+
extension Blob {
26+
var byteArray: [UInt8] {
27+
[UInt8](data)
2228
}
2329
}

Tests/SQLiteTests/Core/StatementTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class StatementTests: SQLiteTestCase {
2222
let statement = try db.prepare("SELECT email FROM users")
2323
XCTAssert(try statement.step())
2424
let blob = statement.row[0] as Blob
25-
XCTAssertEqual("[email protected]", String(bytes: blob.bytes, encoding: .utf8)!)
25+
XCTAssertEqual("[email protected]", String(data: blob.data as Data, encoding: .utf8)!)
2626
}
2727

2828
func test_zero_sized_blob_returns_null() throws {
@@ -31,7 +31,7 @@ class StatementTests: SQLiteTestCase {
3131
try db.run(blobs.create { $0.column(blobColumn) })
3232
try db.run(blobs.insert(blobColumn <- Blob(bytes: [])))
3333
let blobValue = try db.scalar(blobs.select(blobColumn).limit(1, offset: 0))
34-
XCTAssertEqual([], blobValue.bytes)
34+
XCTAssertEqual([], blobValue.byteArray)
3535
}
3636

3737
func test_prepareRowIterator() throws {

Tests/SQLiteTests/FoundationTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class FoundationTests: XCTestCase {
55
func testDataFromBlob() {
66
let data = Data([1, 2, 3])
77
let blob = data.datatypeValue
8-
XCTAssertEqual([1, 2, 3], blob.bytes)
8+
XCTAssertEqual([1, 2, 3], blob.byteArray)
99
}
1010

1111
func testBlobToData() {

0 commit comments

Comments
 (0)