1
0

SwifterSQLiteDatabaseProxy.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //
  2. // SQLiteProxy.swift
  3. // Swifter
  4. // Copyright (c) 2014 Damian Kołakowski. All rights reserved.
  5. //
  6. import Foundation
  7. class SQLiteSequenceElement {
  8. let statementPointer: COpaquePointer
  9. init(pointer: COpaquePointer) {
  10. self.statementPointer = pointer
  11. }
  12. func string(column: Int32) -> String {
  13. if let value = String.fromCString(UnsafePointer<CChar>(sqlite3_column_text(statementPointer, column))) {
  14. return value
  15. }
  16. /// Should never happend :)
  17. /// From 'String.fromCString' documentation:
  18. /// Returns `nil` if the `CString` is `NULL` or if it contains ill-formed
  19. /// UTF-8 code unit sequences.
  20. return "????"
  21. }
  22. func integer(column: Int32) -> Int32 {
  23. return sqlite3_column_int(statementPointer, column)
  24. }
  25. func double(column: Int32) -> Double {
  26. return sqlite3_column_double(statementPointer, column)
  27. }
  28. }
  29. class SQLiteSequenceGenarator: GeneratorType {
  30. let statementPointer: COpaquePointer
  31. init(pointer: COpaquePointer) {
  32. self.statementPointer = pointer
  33. }
  34. func next() -> SQLiteSequenceElement? {
  35. if ( sqlite3_step(statementPointer) == SQLITE_ROW ) {
  36. return SQLiteSequenceElement(pointer: statementPointer)
  37. }
  38. sqlite3_finalize(statementPointer)
  39. return nil
  40. }
  41. }
  42. class SQLiteSequence: SequenceType {
  43. var statementPointer = COpaquePointer()
  44. init?(db: COpaquePointer, sql: String, err: NSErrorPointer? = nil) {
  45. let result = sql.withCString { sqlite3_prepare(db, $0, Int32(strlen($0)), &self.statementPointer, nil) };
  46. if result != SQLITE_OK {
  47. if let err = err { err.memory = error("Can't prepare statement: \(sql), Error: \(result)") }
  48. return nil
  49. }
  50. }
  51. func error(reason: String) -> NSError {
  52. return NSError(domain: "SQLiteSequence", code: 0, userInfo: [NSLocalizedDescriptionKey : reason])
  53. }
  54. func generate() -> SQLiteSequenceGenarator {
  55. return SQLiteSequenceGenarator(pointer: statementPointer)
  56. }
  57. }
  58. class SwifterSQLiteDatabaseProxy: SwifterDatabseProxy {
  59. let name: String
  60. init(name databaseName: String) {
  61. name = databaseName
  62. }
  63. func err(reason: String) -> NSError {
  64. return NSError(domain: "SwifterSQLiteDatabaseProxy", code: 0, userInfo: [NSLocalizedDescriptionKey : reason])
  65. }
  66. func execute<Result>(name: String, sql: String, err: NSErrorPointer? = nil, f: ((SQLiteSequence) -> Result?)? = nil ) -> Result? {
  67. var database = COpaquePointer()
  68. if ( SQLITE_OK == name.withCString { sqlite3_open($0, &database) } ) {
  69. if let sequence = SQLiteSequence(db: database, sql: sql, err: err) {
  70. var result: Result?
  71. if let f = f {
  72. result = f(sequence)
  73. }
  74. sqlite3_close(database)
  75. return result
  76. }
  77. sqlite3_close(database)
  78. }
  79. return nil
  80. }
  81. func scheme(error: NSErrorPointer?) -> [String: [(String, String)]]? {
  82. let tables: [String]? = execute(name, sql: "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;", err: error) { map($0, { $0.string(0) }) }
  83. if let tables = tables {
  84. var scheme = [String: [(String, String)]]()
  85. for table in tables {
  86. let columns: [(String, String)]? = execute(name, sql: "PRAGMA table_info('\(table)');", err: error) { map($0, { ($0.string(1), $0.string(2)) } ) }
  87. if let columns = columns {
  88. scheme[table] = columns
  89. } else {
  90. return nil
  91. }
  92. }
  93. return scheme
  94. }
  95. return nil
  96. }
  97. func createTable(name: String, columns: [String: String], error: NSErrorPointer?) -> Bool {
  98. return false
  99. }
  100. func deleteTable(name: String, error: NSErrorPointer?) -> Bool {
  101. return false
  102. }
  103. func insertColumn(table: String, column: String, error: NSErrorPointer?) -> Bool {
  104. return false
  105. }
  106. func deleteColumn(table: String, column: String, error: NSErrorPointer?) -> Bool {
  107. return false
  108. }
  109. func copyColumn(table: String, from: String, to: String, error: NSErrorPointer?) -> Bool {
  110. return false
  111. }
  112. func insertRow(table: String, value: [String: String], error: NSErrorPointer?) -> Int {
  113. return 0
  114. }
  115. func deleteRow(table: String, id: Int, error: NSErrorPointer?) -> Bool {
  116. return false
  117. }
  118. }