FMDBTests.swift 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import XCTest
  2. import SQLite3
  3. @testable import FMDB
  4. final class FMDBTests: FMDBTempDBTests {
  5. let tempPath = "/tmp/FMDBTests.db"
  6. override func setUp() {
  7. }
  8. func testExample() throws {
  9. do {
  10. NSLog("Is SQLite compiled with it's thread safe options turned on? %@!", FMDatabase.isSQLiteThreadSafe() ? "Yes" : "No");
  11. let db = emptyDatabase(path: tempPath)
  12. XCTAssert(try db.open())
  13. let rs = try db.executeQuery("select 'hi'")
  14. XCTAssert(try rs.next())
  15. print(rs.string(0) as Any)
  16. XCTAssert(rs.string(0) == "hi")
  17. XCTAssert(db.close())
  18. }
  19. catch {
  20. print(error)
  21. XCTAssert(false)
  22. }
  23. //_ = db.executeUpdate(statement: "create table test (a text, b text, c integer, d double, e double)");
  24. }
  25. func testNextWithError_WithoutError() throws
  26. {
  27. do {
  28. let db = emptyDatabase(path: tempPath)
  29. XCTAssert(try db.open())
  30. try db.executeUpdate("CREATE TABLE testTable(key INTEGER PRIMARY KEY, value INTEGER)")
  31. try db.executeUpdate("INSERT INTO testTable (key, value) VALUES (1, 2)")
  32. try db.executeUpdate("INSERT INTO testTable (key, value) VALUES (2, 4)")
  33. let resultSet = try db.executeQuery("SELECT * FROM testTable WHERE key=1")
  34. XCTAssertNotNil(resultSet)
  35. XCTAssertTrue(try resultSet.next())
  36. XCTAssertFalse(try resultSet.next())
  37. resultSet.close()
  38. }
  39. catch {
  40. print(error)
  41. XCTAssert(false)
  42. }
  43. }
  44. func testNextWithError_WithBusyError() throws
  45. {
  46. do {
  47. let db = emptyDatabase(path: tempPath)
  48. XCTAssert(try db.open())
  49. try db.executeUpdate("CREATE TABLE testTable(key INTEGER PRIMARY KEY, value INTEGER)")
  50. try db.executeUpdate("INSERT INTO testTable (key, value) VALUES (1, 2)")
  51. try db.executeUpdate("INSERT INTO testTable (key, value) VALUES (2, 4)")
  52. let resultSet = try db.executeQuery("SELECT * FROM testTable WHERE key=1")
  53. XCTAssertNotNil(resultSet)
  54. let newDB = FMDatabase.database(with: tempPath)
  55. XCTAssert(try newDB.open())
  56. try newDB.beginExclusiveTransaction()
  57. var caught = false
  58. do {
  59. let b = try resultSet.next()
  60. XCTAssertFalse(b) // we never actually get here :/
  61. }
  62. catch FMDBError.sqlite3ErrorCode(let sqlite3Code) {
  63. caught = true
  64. XCTAssertEqual(sqlite3Code, SQLITE_BUSY, "SQLITE_BUSY should be the last error")
  65. }
  66. XCTAssertTrue(caught)
  67. try newDB.commit()
  68. resultSet.close()
  69. }
  70. catch {
  71. print(error)
  72. XCTAssert(false)
  73. }
  74. }
  75. func testNextWithError_WithMisuseError() throws
  76. {
  77. do {
  78. let db = emptyDatabase(path: tempPath)
  79. XCTAssert(try db.open())
  80. try db.executeUpdate("CREATE TABLE testTable(key INTEGER PRIMARY KEY, value INTEGER)")
  81. try db.executeUpdate("INSERT INTO testTable (key, value) VALUES (1, 2)")
  82. try db.executeUpdate("INSERT INTO testTable (key, value) VALUES (2, 4)")
  83. let resultSet = try db.executeQuery("SELECT * FROM testTable WHERE key=9")
  84. XCTAssertNotNil(resultSet)
  85. XCTAssertFalse(try resultSet.next())
  86. var caught = false
  87. do {
  88. try resultSet.next()
  89. }
  90. catch FMDBError.sqlite3ErrorCode(let sqlite3Code) {
  91. caught = true
  92. XCTAssertEqual(sqlite3Code, SQLITE_MISUSE, "SQLITE_MISUSE should be the last error")
  93. }
  94. XCTAssertTrue(caught)
  95. }
  96. catch {
  97. print(error)
  98. XCTAssert(false)
  99. }
  100. }
  101. func testColumnTypes() throws
  102. {
  103. do {
  104. let db = emptyDatabase(path: tempPath)
  105. XCTAssert(try db.open())
  106. try db.executeUpdate("CREATE TABLE testTable (intValue INTEGER, floatValue FLOAT, textValue TEXT, blobValue BLOB)")
  107. let sql = "INSERT INTO testTable (intValue, floatValue, textValue, blobValue) VALUES (?, ?, ?, ?)";
  108. let data = NSString("foo").data(using: String.Encoding.utf8.rawValue)
  109. let zeroLengthData = NSData()
  110. let n = NSNull()
  111. try db.executeUpdate(sql, 42, Double.pi, "test", data as Any)
  112. try db.executeUpdate(sql, n, n, n, n)
  113. try db.executeUpdate(sql, n, n, n, zeroLengthData)
  114. let resultSet = try db.executeQuery("SELECT * FROM testTable order by rowid")
  115. XCTAssertNotNil(resultSet)
  116. // Weird but true. If we grab the value of the blob as a string (using resultSet.stringFor(columnIndex: 3)) before
  117. // grabbing it as a blob (or using it as resultSet.typeForColumn("blobValue")), then it's type will be cached in
  118. // sqlite somewhere as SQLITE_TEXT. So, in this order:
  119. // resultSet.typeForColumnIndex(3) // 4
  120. // resultSet.stringFor(columnIndex: 3) // "foo"
  121. // resultSet.typeForColumnIndex(3) // 3
  122. // That's kind of odd.
  123. XCTAssertTrue(try resultSet.next())
  124. XCTAssertEqual(resultSet.typeForColumn("intValue"), SqliteValueType.SqliteValueTypeInteger.rawValue)
  125. XCTAssertEqual(resultSet.typeForColumn("floatValue"), SqliteValueType.SqliteValueTypeFloat.rawValue)
  126. XCTAssertEqual(resultSet.typeForColumn("textValue"), SqliteValueType.SqliteValueTypeText.rawValue)
  127. XCTAssertEqual(resultSet.typeForColumn("blobValue"), SqliteValueType.SqliteValueTypeBlob.rawValue)
  128. XCTAssertNotNil(resultSet.data("blobValue"))
  129. XCTAssertTrue(try resultSet.next())
  130. XCTAssertEqual(resultSet.typeForColumn("intValue"), SqliteValueType.SqliteValueTypeNull.rawValue)
  131. XCTAssertEqual(resultSet.typeForColumn("floatValue"), SqliteValueType.SqliteValueTypeNull.rawValue)
  132. XCTAssertEqual(resultSet.typeForColumn("textValue"), SqliteValueType.SqliteValueTypeNull.rawValue)
  133. XCTAssertEqual(resultSet.typeForColumn("blobValue"), SqliteValueType.SqliteValueTypeNull.rawValue)
  134. XCTAssertNil(resultSet.data("blobValue"))
  135. XCTAssertTrue(try resultSet.next())
  136. XCTAssertEqual(resultSet.typeForColumn("blobValue"), SqliteValueType.SqliteValueTypeBlob.rawValue)
  137. XCTAssertNil(resultSet.data("blobValue"))
  138. }
  139. catch {
  140. print(error)
  141. XCTAssert(false)
  142. }
  143. }
  144. func testURLOpen() throws {
  145. let tempFolder = NSURL.init(fileURLWithPath: NSTemporaryDirectory())
  146. let fileURL = tempFolder.appendingPathComponent(NSUUID().uuidString)
  147. let fileManager = FileManager()
  148. try? fileManager.removeItem(at: fileURL! as URL)
  149. let db = FMDatabase.database(with: fileURL!)
  150. XCTAssert(try db.open(), "Open should succeed")
  151. XCTAssertTrue(((db.databaseURL()?.isEqual(to: fileURL)) != nil), "URLs should be the same");
  152. XCTAssert(db.close(), "Close should succeed")
  153. }
  154. }