Advertisement
JetForMe

SQLite.swoft

Dec 31st, 2020 (edited)
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 4.42 KB | None | 0 0
  1. //
  2. //  SQLite.swift
  3. //
  4.  
  5. import Foundation
  6. import SQLite3
  7.  
  8.  
  9.  
  10. class
  11. SQLite
  12. {
  13.     init(url inURL: URL)
  14.         throws
  15.     {
  16.         let result = sqlite3_open(inURL.path, &self.db)
  17.         try throwIfNotOK(result)
  18.     }
  19.    
  20.     func
  21.     beginTransaction()
  22.         throws
  23.     {
  24.         try exec(sql: "begin")
  25.     }
  26.    
  27.     func
  28.     commit()
  29.         throws
  30.     {
  31.         try exec(sql: "commit")
  32.     }
  33.    
  34.     func
  35.     rollback()
  36.         throws
  37.     {
  38.         try exec(sql: "rollback")
  39.     }
  40.    
  41.     func
  42.     exec(sql inSQL: String)
  43.         throws
  44.     {
  45.         let result = sqlite3_exec(self.db, inSQL, nil, nil, nil)
  46.         try throwIfNotOK(result)
  47.     }
  48.    
  49.     func
  50.     prepare(sql inSQL: String)
  51.         throws
  52.     {
  53.         if self.stmt != nil
  54.         {
  55.         }
  56.        
  57.         let result = sqlite3_prepare_v2(self.db, inSQL, -1, &self.stmt, nil)
  58.         try throwIfNotOK(result)
  59.     }
  60.    
  61.     func
  62.     bind(idx inIdx: Int, val inVal: Int)
  63.         throws
  64.     {
  65.         guard
  66.             let stmt = self.stmt
  67.         else
  68.         {
  69.             throw Errors.noStatementPrepared
  70.         }
  71.        
  72.         let result = sqlite3_bind_int64(stmt, Int32(inIdx), Int64(inVal))
  73.         try throwIfNotOK(result)
  74.     }
  75.    
  76.     func
  77.     bind(idx inIdx: Int, val inVal: String)
  78.         throws
  79.     {
  80.         guard
  81.             let stmt = self.stmt
  82.         else
  83.         {
  84.             throw Errors.noStatementPrepared
  85.         }
  86.        
  87.         print("Binding idx \(inIdx) to text val [\(inVal)]")
  88.         let result = sqlite3_bind_text(stmt, Int32(inIdx), inVal, -1, nil)
  89.         try throwIfNotOK(result)
  90.     }
  91.    
  92.     func
  93.     bind(idx inIdx: Int, val inVal: Float)
  94.         throws
  95.     {
  96.         try bind(idx: inIdx, val: Double(inVal))
  97.     }
  98.    
  99.     func
  100.     bind(idx inIdx: Int, val inVal: Double)
  101.         throws
  102.     {
  103.         guard
  104.             let stmt = self.stmt
  105.         else
  106.         {
  107.             throw Errors.noStatementPrepared
  108.         }
  109.        
  110.         print("Binding idx \(inIdx) to double val [\(inVal)]")
  111.         let result = sqlite3_bind_double(stmt, Int32(inIdx), inVal)
  112.         try throwIfNotOK(result)
  113.     }
  114.    
  115.     func
  116.     bind(idx inIdx: Int, val inVal: Date)
  117.         throws
  118.     {
  119.         try bind(idx: inIdx, val: inVal.timeIntervalSinceReferenceDate)
  120.     }
  121.    
  122.     func
  123.     bind(idx inIdx: Int, val inVal: UUID)
  124.         throws
  125.     {
  126.         try bind(idx: inIdx, val: inVal.uuidString)
  127.     }
  128.    
  129. //  func
  130. //  bind(idx inIdx: Int, val inVal: UUID)
  131. //      throws
  132. //  {
  133. //      guard
  134. //          let stmt = self.stmt
  135. //      else
  136. //      {
  137. //          throw Errors.noStatementPrepared
  138. //      }
  139. //
  140. //      let result = sqlite3_bind_blob(stmt, Int32(inIdx), d, len) { (inPtr) in
  141. //          <#code#>
  142. //      }
  143. //      try throwIfNotOK(result)
  144. //  }
  145.    
  146.     func
  147.     step()
  148.         throws
  149.     {
  150.         guard
  151.             let stmt = self.stmt
  152.         else
  153.         {
  154.             throw Errors.noStatementPrepared
  155.         }
  156.        
  157.         let result = sqlite3_step(stmt)
  158.         if result == SQLITE_DONE        //  success
  159.         {
  160.             return
  161.         }
  162.        
  163.         try throwIfNotOK(result)
  164.     }
  165.    
  166.     func
  167.     reset()
  168.         throws
  169.     {
  170.         guard
  171.             let stmt = self.stmt
  172.         else
  173.         {
  174.             throw Errors.noStatementPrepared
  175.         }
  176.        
  177.         let result = sqlite3_reset(stmt)
  178.         try throwIfNotOK(result)
  179.     }
  180.    
  181.     func
  182.     finalize()
  183.         throws
  184.     {
  185.         guard
  186.             let stmt = self.stmt
  187.         else
  188.         {
  189.             throw Errors.noStatementPrepared
  190.         }
  191.        
  192.         let result = sqlite3_finalize(stmt)
  193.         try throwIfNotOK(result)
  194.         self.stmt = nil
  195.     }
  196.    
  197.     func
  198.     throwIfNotOK(_ inResult: Int32)
  199.         throws
  200.     {
  201.         if inResult != SQLITE_OK
  202.         {
  203.             let errMsg = String(cString: sqlite3_errmsg(self.db))
  204.             throw Errors.create(inResult, msg: errMsg)
  205.         }
  206.     }
  207.    
  208.     var
  209.     stmtString: String?
  210.     {
  211.         guard
  212.             let stmt = self.stmt
  213.         else
  214.         {
  215.             return nil
  216.         }
  217.        
  218.         guard let s = sqlite3_expanded_sql(stmt) else { return nil }
  219.         let count = strlen(s)
  220.         let ss = s.withMemoryRebound(to: Int8.self, capacity: count) { String(cString: $0) }
  221.         sqlite3_free(s)
  222.         return ss
  223.     }
  224.    
  225.     fileprivate
  226.     var errorMessage: String?
  227.     {
  228.         if let errorPointer = sqlite3_errmsg(self.db)
  229.         {
  230.             let errorMessage = String(cString: errorPointer)
  231.             return errorMessage
  232.         }
  233.         else
  234.         {
  235.             return nil
  236.         }
  237.     }
  238.  
  239.     var db: OpaquePointer!
  240.     var stmt: OpaquePointer?
  241.    
  242.     enum
  243.     Errors : Error
  244.     {
  245.         case unknownError(Int, String?)
  246.         case noStatementPrepared
  247.        
  248.         static
  249.         func
  250.         create(_ inSQLiteError: Int32, msg inMsg: String? = nil)
  251.             -> Errors
  252.         {
  253.             switch (inSQLiteError)
  254.             {
  255.                 default:
  256.                     return .unknownError(Int(inSQLiteError), inMsg)
  257.             }
  258.         }
  259.     }
  260. }
  261.  
  262. extension
  263. UnsafeMutablePointer where Pointee == Int8
  264. {
  265.     var
  266.     string: String
  267.     {
  268.         let count = strlen(self)
  269.         let message = self.withMemoryRebound(to: Int8.self, capacity: count) { String(cString: $0) }
  270.         sqlite3_free(self)
  271.         return message
  272.     }
  273. }
  274.  
  275. extension
  276. String
  277. {
  278.     init?(_ inP: UnsafeMutablePointer<Int8>?)
  279.     {
  280.         guard
  281.             let p = inP
  282.         else
  283.         {
  284.             return nil
  285.         }
  286.        
  287.         self.init(p.string)
  288.     }
  289. }
  290.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement