{"id":274467,"date":"2016-02-17T17:18:04","date_gmt":"2016-02-17T14:18:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=274467"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=274467","title":{"rendered":"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 SQLLite \u043a \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e iOS \u0447\u0435\u0440\u0435\u0437 FMDB \u043d\u0430 Xcode \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Swift"},"content":{"rendered":"<p>       \u0421\u0442\u043e\u043b\u043a\u043d\u0443\u0432\u0448\u0438\u0441\u044c \u0441 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c SQLLite \u043a \u0441\u0432\u043e\u0435\u043c\u0443 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e iOS \u0447\u0435\u0440\u0435\u0437 FMDB, \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0433\u0430\u0439\u0434\u0430 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435. \u0418 \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0434\u043b\u044f Swift. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u0433\u0430\u0439\u0434\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0430\u0439\u043b\u044b \u0441 objective-c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043d\u0430\u0434\u043e \u0436\u0434\u0430\u0442\u044c \u043f\u043e\u0440\u0442\u0430 FMDB \u043d\u0430 Swift.<\/p>\n<p>  \u0421\u043a\u0430\u0447\u0430\u0442\u044c FMDB \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/github.com\/ccgus\/fmdb\">\u0442\u0443\u0442<\/a>.<\/p>\n<p>  \u0412 FMDB \u0442\u0440\u0438 main class:<\/p>\n<p>  FMDatabase \u2014 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 SQLite. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f SQL-\u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432.<br \/>  FMResultSet \u2014 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e FMDatabase.<br \/>  FMDatabaseQueue \u2014 \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441. \u041f\u0440\u0438\u043c\u0435\u0440 \u0432 8 \u043f\u0443\u043d\u043a\u0442\u0435.<\/p>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u0430. \u041e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u0441\u044f \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438\u043b\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0438\/\u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<pre><code class=\"objectivec\">if (![db open]) {     [db release];     return; } <\/code><\/pre>\n<p>  <b>\u0428\u0430\u0433\u0438:<\/b><br \/>  <a name=\"habracut\"><\/a><br \/>  <b>1)<\/b> \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 &#8216;libsqlite3&#8217; \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 FMDB \u0444\u0430\u0439\u043b\u044b \u0432 \u0432\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442. (\u0434\u0430, \u043e\u043d\u0438 \u043d\u0430 objective-c).<\/p>\n<p>  <b>2)<\/b> \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u00abFMDB-Bridging-Header.h\u00bb. \u0412\u043d\u0443\u0442\u0440\u0438 \u00abBridging-Header.h\u00bb \u043d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435: #import \u00abFMDB.h\u00bb.<\/p>\n<p>  <b>3)<\/b> \u0417\u0430\u0439\u0434\u0438\u0442\u0435 \u0432 Build Settings -&gt; Swift Compiler \u2014 Code Generation \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043a &#8216;Objective-C Bridging Header&#8217;: FMDB-Bridging-Header.h.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u0432 \u043f\u0430\u043f\u043a\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0442\u043e \u0442\u0430\u043a: \u0418\u041c\u042f_\u041f\u0410\u041f\u041a\u0418\/FMDB-Bridging-Header.h<\/p>\n<p>  <b>4)<\/b> \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0432 \u0412\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 SQLite database. \u0412 \u044d\u0442\u043e\u043c \u0433\u0430\u0439\u0434\u0435 \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 &#8216;tempdb.sqlite&#8217; \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0441 \u043e\u0434\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u0432\u043d\u0443\u0442\u0440\u0438:<\/p>\n<p>  CREATE TABLE test_tb ( test_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, keywordtext TEXT)<\/p>\n<p>  <b>5) <\/b>\u0412 \u0432\u0430\u0448\u0435\u043c AppDelegate.swift&#8217;s class AppDelegate \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435: var dbFilePath: NSString = NSString()<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440:  <\/p>\n<pre><code class=\"objectivec\">import UIKit  @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {  var window: UIWindow? var navi: UINavigationController? var dbFilePath: NSString = NSString()  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -&gt; Bool { .... <\/code><\/pre>\n<p>  <b>6)<\/b> \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432 AppDelegate.swift&#8217;s class AppDelegate:<\/p>\n<pre><code class=\"objectivec\">\/\/ MARK: - FMDB \u00a0 let DATABASE_RESOURCE_NAME = &quot;tempdb&quot; let DATABASE_RESOURCE_TYPE = &quot;sqlite&quot; let DATABASE_FILE_NAME = &quot;tempdb.sqlite&quot; \u00a0 func initializeDb() -&gt; Bool {         let documentFolderPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String \u00a0         let dbfile = &quot;\/&quot; + DATABASE_FILE_NAME; \u00a0         self.dbFilePath = documentFolderPath.stringByAppendingString(dbfile) \u00a0         let filemanager = NSFileManager.defaultManager()         if (!filemanager.fileExistsAtPath(dbFilePath) ) { \u00a0             let backupDbPath = NSBundle.mainBundle().pathForResource(DATABASE_RESOURCE_NAME, ofType: DATABASE_RESOURCE_TYPE) \u00a0             if (backupDbPath == nil) {                 return false             } else {                 var error: NSError?                 let copySuccessful = filemanager.copyItemAtPath(backupDbPath, toPath:dbFilePath, error: &error)                 if !copySuccessful {                     println(&quot;copy failed: \\(error?.localizedDescription)&quot;)                     return false                 } \u00a0             } \u00a0         }         return true \u00a0     } <\/code><\/pre>\n<p>  <b>7)<\/b> \u0412\u044b\u0437\u043e\u0432\u0438\u0442\u0435 \u0432 AppDelegate.swift&#8217;s func application:<\/p>\n<pre><code class=\"objectivec\">func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -&gt; Bool {  if self.initializeDb() { NSLog(&quot;Successful db copy&quot;) } <\/code><\/pre>\n<p>  <b>8)<\/b> \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 UITableViewController) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f FMDB:<\/p>\n<pre><code class=\"objectivec\">import UIKit \u00a0 class SecondViewController: UIViewController { \u00a0 \/\/ MARK: - .H \u00a0     @IBOutlet var dataTable: UITableView?     var dataArray:[MultiField] = [] \u00a0 \/\/ MARK: - .M \u00a0     required init(coder: NSCoder) {         fatalError(&quot;NSCoding not supported&quot;)     } \u00a0     override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {         super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)         \/\/ Custom initialization     } \u00a0     override func viewDidLoad() {         super.viewDidLoad() \u00a0         \/\/ Do any additional setup after loading the view.         self.title = &quot;FMDB Using Swift&quot; \u00a0         let mainDelegate: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate \u00a0         \/\/ initialize FMDB         let db: FMDatabase = FMDatabase(path:mainDelegate.dbFilePath)         if (db.open() == nil) {             NSLog(&quot;error opening db&quot;)         } \u00a0         \/\/ \u0432\u0441\u0442\u0430\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445         let addQuery = &quot;INSERT INTO test_tb (name, keywordtext) VALUES ('excalibur', 'hot')&quot;         let addSuccessful = db.executeUpdate(addQuery, withArgumentsInArray: nil)         if !addSuccessful {             println(&quot;insert failed: \\(db.lastErrorMessage())&quot;)         }         \/\/ \u0432\u0441\u0442\u0430\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 - \u043a\u043e\u043d\u0435\u0446 \u00a0         \/\/ update \u0434\u0430\u043d\u043d\u044b\u0445         let updateQuery = &quot;UPDATE test_tb SET keywordtext = 'cool' WHERE name = 'excalibur' &quot;         let updateSuccessful = db.executeUpdate(updateQuery, withArgumentsInArray: nil)         if !updateSuccessful {             println(&quot;update failed: \\(db.lastErrorMessage())&quot;)         }         \/\/ update \u0434\u0430\u043d\u043d\u044b\u0445 - \u043a\u043e\u043d\u0435\u0446 \u00a0         \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0431\u0430\u0437\u044b \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438\u0445 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 UITableView         let mainQuery = &quot;SELECT name, keywordtext FROM test_tb&quot;         let rsMain: FMResultSet? = db.executeQuery(mainQuery, withArgumentsInArray: []) \u00a0         while (rsMain!.next() == true) {             let productName = rsMain?.stringForColumn(&quot;name&quot;)             let keywords = rsMain?.stringForColumn(&quot;keywordtext&quot;) \u00a0             let multiField = MultiField(aField1: productName!, aField2: keywords!)             self.dataArray.append(multiField) \u00a0         }         \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 - \u043a\u043e\u043d\u0435\u0446 \u00a0         \/\/ \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445         let delQuery = &quot;DELETE FROM test_tb WHERE name = 'excalibur' &quot;         let deleteSuccessful = db.executeUpdate(delQuery, withArgumentsInArray: nil)         if !deleteSuccessful {             println(&quot;delete failed: \\(db.lastErrorMessage())&quot;)         }         \/\/ \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 - \u043a\u043e\u043d\u0435\u0446 \u00a0         \/\/ \u043f\u0440\u0438\u043c\u0435\u0440: \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a         let rsTemp: FMResultSet? = db.executeQuery(&quot;SELECT count(*) AS numrows FROM test_tb&quot;, withArgumentsInArray: [])         rsTemp!.next()         let numrows = rsTemp?.intForColumn(&quot;numrows&quot;) \u00a0         NSLog(&quot;numrows: \\(numrows)&quot;)         \/\/\u043f\u0440\u0438\u043c\u0435\u0440: \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a\u0438 - \u043a\u043e\u043d\u0435\u0446 \u00a0         db.close() \u00a0     } \u00a0     override func didReceiveMemoryWarning() {         super.didReceiveMemoryWarning()         \/\/ Dispose of any resources that can be recreated.     } \u00a0 \/\/ MARK: - TableView DataSource \u00a0  func numberOfSectionsInTableView(tableView: UITableView!) -&gt; Int {         return 1     } \u00a0     func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -&gt; Int { \u00a0         return self.dataArray.count     } \u00a0     func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -&gt; UITableViewCell!  { \u00a0         let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: &quot;FMDBTest&quot;) \u00a0         let multiField: MultiField = self.dataArray[indexPath.row] \u00a0         let num = indexPath.row + 1 \u00a0         cell.textLabel.text = &quot;\\(num). \\(multiField.field1!)&quot;         cell.detailTextLabel.text = multiField.field2 \u00a0         return cell     } \/\/ MARK: - UITableViewDelegate \u00a0     func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {         tableView.deselectRowAtIndexPath(indexPath, animated: true)    } }<\/code><\/pre>\n<p>  <b>9)<\/b> \u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0444\u0438\u0448\u0435\u043a, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043e\u0442\u043e\u043a\u0430 FMDB \u0447\u0435\u0440\u0435\u0437 FMDatabaseQueue.<\/p>\n<pre><code class=\"objectivec\">var queue: FMDatabaseQueue? \u00a0 func testDatabaseQueue() {     let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String     let databasePath = documentsFolder.stringByAppendingPathComponent(&quot;test.sqlite&quot;) \u00a0     queue = FMDatabaseQueue(path: databasePath) \u00a0     \/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b &lt;source lang=&quot;objectivec&quot;&gt;\u00a0     queue?.inDatabase() {         db in \u00a0         var success = db.executeUpdate(&quot;create table test (id integer primary key autoincrement, a text)&quot;, withArgumentsInArray:nil) \u00a0         if !success {             println(&quot;table create failure: \\(db.lastErrorMessage())&quot;)             return         }     } <\/code><\/pre>\n<p>   \/\/ \u0432\u0441\u0442\u0430\u0432\u043a\u0430 \u043f\u044f\u0442\u0438 \u0441\u0442\u0440\u043e\u043a<\/p>\n<pre><code class=\"objectivec\">   queue?.inTransaction() {         db, rollback in \u00a0         for i in 0 ..&lt; 5 {             if !db.executeUpdate(&quot;insert into test (a) values (?)&quot;, withArgumentsInArray: [&quot;Row \\(i)&quot;]) {                 println(&quot;insert \\(i) failure: \\(db.lastErrorMessage())&quot;)                 rollback.initialize(true)                 return             }         }     }<\/code><\/pre>\n<p>  \u00a0 \/\/\u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u043e \u0441\u043e\u0437\u043d\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0448\u0438\u0431\u0435\u043c\u0441\u044f \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043e\u043d \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e<\/p>\n<pre><code class=\"objectivec\">    queue?.inTransaction() {         db, rollback in \u00a0         for i in 5 ..&lt; 10 {             let success = db.executeUpdate(&quot;insert into test (a) values (?)&quot;, withArgumentsInArray: [&quot;Row \\(i)&quot;]) \u00a0             if !success {                 println(&quot;insert \\(i) failure: \\(db.lastErrorMessage())&quot;)                 rollback.initialize(true)                 return             } \u00a0             if (i == 7) {                 rollback.initialize(true)             }         }     }<\/code><\/pre>\n<p>   \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u044b\u0435 \u043f\u044f\u0442\u044c \u0441\u0442\u0440\u043e\u043a \u0442\u0430\u043c<\/p>\n<pre><code class=\"objectivec\">    queue?.inDatabase() {         db in \u00a0         if let rs = db.executeQuery(&quot;select * from test&quot;, withArgumentsInArray:nil) { \u00a0             while rs.next() {                 println(rs.resultDictionary())             }         } else {             println(&quot;select failure: \\(db.lastErrorMessage())&quot;)         } \u00a0     } <\/code><\/pre>\n<p>\u00a0<br \/>   \/\/ \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443<\/p>\n<p>  \u00a0<\/p>\n<pre><code class=\"objectivec\">    queue?.inDatabase() {         db in \u00a0         let success = db.executeUpdate(&quot;drop table test&quot;, withArgumentsInArray:nil) \u00a0         if !success {             println(&quot;table drop failure: \\(db.lastErrorMessage())&quot;)             return         }     } } <\/code><\/pre>\n<p>  <b>10)<\/b> \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043d\u0430 \u0437\u0430\u043a\u0443\u0441\u043a\u0443. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 executeUpdate(values:) \u0432 Swift2:<\/p>\n<pre><code class=\"objectivec\">do {     let identifier = 42     let name = &quot;Liam O'Flaherty (\\&quot;the famous Irish author\\&quot;)&quot;     let date = NSDate()     let comment: String? = nil      try db.executeUpdate(&quot;INSERT INTO authors (identifier, name, date, comment) VALUES (?, ?, ?, ?)&quot;, values: [identifier, name, date, comment ?? NSNull()]) } catch {     print(&quot;error = \\(error)&quot;) } <\/code><\/pre>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 queue:<\/p>\n<pre><code class=\"objectivec\">queue.inTransaction { db, rollback in     do {         try db.executeUpdate(&quot;INSERT INTO myTable VALUES (?)&quot;, values: [1])         try db.executeUpdate(&quot;INSERT INTO myTable VALUES (?)&quot;, values: [2])         try db.executeUpdate(&quot;INSERT INTO myTable VALUES (?)&quot;, values: [3])          if whoopsSomethingWrongHappened {             rollback.memory = true             return         }          try db.executeUpdate(&quot;INSERT INTO myTable VALUES (?)&quot;, values: [4])     } catch {         rollback.memory = true         print(error)     } } <\/code><\/pre>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"objectivec\">let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false) let fileURL = documents.URLByAppendingPathComponent(&quot;test.sqlite&quot;)  let database = FMDatabase(path: fileURL.path)  if !database.open() {     print(&quot;Unable to open database&quot;)     return }  do {     try database.executeUpdate(&quot;create table test(x text, y text, z text)&quot;, values: nil)     try database.executeUpdate(&quot;insert into test (x, y, z) values (?, ?, ?)&quot;, values: [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;])     try database.executeUpdate(&quot;insert into test (x, y, z) values (?, ?, ?)&quot;, values: [&quot;e&quot;, &quot;f&quot;, &quot;g&quot;])      let rs = try database.executeQuery(&quot;select x, y, z from test&quot;, values: nil)     while rs.next() {         let x = rs.stringForColumn(&quot;x&quot;)         let y = rs.stringForColumn(&quot;y&quot;)         let z = rs.stringForColumn(&quot;z&quot;)         print(&quot;x = \\(x); y = \\(y); z = \\(z)&quot;)     } } catch let error as NSError {     print(&quot;failed: \\(error.localizedDescription)&quot;) }  database.close() <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u043f\u0438\u0448\u0435\u0442\u0435, \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043f\u043e\u043c\u043e\u0447\u044c.       <\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/277423\/\"> https:\/\/habrahabr.ru\/post\/277423\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0421\u0442\u043e\u043b\u043a\u043d\u0443\u0432\u0448\u0438\u0441\u044c \u0441 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c SQLLite \u043a \u0441\u0432\u043e\u0435\u043c\u0443 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e iOS \u0447\u0435\u0440\u0435\u0437 FMDB, \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0433\u0430\u0439\u0434\u0430 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435. \u0418 \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0434\u043b\u044f Swift. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u0433\u0430\u0439\u0434\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0430\u0439\u043b\u044b \u0441 objective-c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043d\u0430\u0434\u043e \u0436\u0434\u0430\u0442\u044c \u043f\u043e\u0440\u0442\u0430 FMDB \u043d\u0430 Swift.<\/p>\n<p>  \u0421\u043a\u0430\u0447\u0430\u0442\u044c FMDB \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/github.com\/ccgus\/fmdb\">\u0442\u0443\u0442<\/a>.<\/p>\n<p>  \u0412 FMDB \u0442\u0440\u0438 main class:<\/p>\n<p>  FMDatabase \u2014 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 SQLite. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f SQL-\u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432.<br \/>  FMResultSet \u2014 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e FMDatabase.<br \/>  FMDatabaseQueue \u2014 \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441. \u041f\u0440\u0438\u043c\u0435\u0440 \u0432 8 \u043f\u0443\u043d\u043a\u0442\u0435.<\/p>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u0430. \u041e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u0441\u044f \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438\u043b\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0438\/\u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<pre><code class=\"objectivec\">if (![db open]) {     [db release];     return; } <\/code><\/pre>\n<p>  <b>\u0428\u0430\u0433\u0438:<\/b>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-274467","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/274467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=274467"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/274467\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=274467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=274467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=274467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}