{"id":18479204,"url":"https://github.com/kevinzhourafael/activesqlite","last_synced_at":"2025-04-08T15:34:24.686Z","repository":{"id":37734378,"uuid":"95529793","full_name":"KevinZhouRafael/ActiveSQLite","owner":"KevinZhouRafael","description":"ActiveSQLite is an helper of SQLite.Swift. It can let you use SQLite.swift easily.","archived":false,"fork":false,"pushed_at":"2023-01-20T13:12:49.000Z","size":2228,"stargazers_count":66,"open_issues_count":5,"forks_count":14,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-09-16T18:34:48.142Z","etag":null,"topics":["activerecord","coredata","database","fmdb","magicalrecord","orm","realm","sqlite","sqlite-database","sqlite-ios","sqlite-orm","sqlite-swift","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KevinZhouRafael.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-27T07:24:04.000Z","updated_at":"2024-08-02T01:45:25.000Z","dependencies_parsed_at":"2023-02-05T04:31:25.502Z","dependency_job_id":null,"html_url":"https://github.com/KevinZhouRafael/ActiveSQLite","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinZhouRafael%2FActiveSQLite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinZhouRafael%2FActiveSQLite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinZhouRafael%2FActiveSQLite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinZhouRafael%2FActiveSQLite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KevinZhouRafael","download_url":"https://codeload.github.com/KevinZhouRafael/ActiveSQLite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247872104,"owners_count":21010175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activerecord","coredata","database","fmdb","magicalrecord","orm","realm","sqlite","sqlite-database","sqlite-ios","sqlite-orm","sqlite-swift","swift"],"created_at":"2024-11-06T12:13:47.149Z","updated_at":"2025-04-08T15:34:22.966Z","avatar_url":"https://github.com/KevinZhouRafael.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ActiveSQLite\n\n[![Version](https://img.shields.io/cocoapods/v/ActiveSQLite.svg?style=flat)](http://cocoapods.org/pods/ActiveSQLite)\n\u003c!--[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)--\u003e\n[![License](https://img.shields.io/cocoapods/l/ActiveSQLite.svg?style=flat)](http://cocoapods.org/pods/ActiveSQLite)\n[![Platform](https://img.shields.io/cocoapods/p/ActiveSQLite.svg?style=flat)](http://cocoapods.org/pods/ActiveSQLite)\n\n\nActiveSQLite is an helper of [SQLite.Swift](https://github.com/stephencelis/SQLite.swift). It can let you use SQLite.swift easily.\u003cp\u003e\nThere is a project named [Reed downloader](https://github.com/KevinZhouRafael/Reed) used ActiveSQLite.\u003cp\u003e\n[**中文说明**](README_cn.md)\n\n## Features\n\n - [x] Support all Features of SQLite.swift.\n - [x] Auto create tables. Auto add columns of id , created\\_at , updated\\_at .\n - [x] Auto set values to attributes of models frome query sql \n - [x] Mapping name of table with name of model, mapping attribute names with column names\n - [x] Support Transcation and Asynchronous\n - [x] A flexible, chainable, lazy-executing query layer\n - [x] Query use String or Expression\u003cT\u003e of SQLite.swift\n - [x] Logger level\n - [ ] Runtime Encoding to Codable Encoding\n - [ ] Complete Protocol Oriented Programming\n - [ ] Table relations\n - [ ] Cache and Faults value\n\n\n## Example\n\nTo run the ActiveSQLiteTests target of project.\n\n\n## Usage\n\n```swift\nimport ActiveSQLite\n\nclass Product:ASModel{\n    var name:String = \"\"\n    var price:NSNumber = NSNumber(value:0.0)\n    var desc:String?\n    var publish_date:NSDate?\n}\n\n//save\nlet product = Product()\nproduct.name = \"iPhone 7\"\nproduct.price = NSNumber(value:599)\ntry! product.save()\n\n//Query\nlet p = Product.findFirst(\"name\",value:\"iPhone\")\n\n//or \nlet name = Expression\u003cString\u003e(\"name\")\nlet p = Product.findAll(name == \"iPhone\").first\n//id = 1, name = iPhone 7, price = 599, desc = nil,  publish_date = nil, created_at = 1498616987587.237, updated_at = 1498616987587.237, \n\n//Update\np.name = \"iPad\"\ntry! p.update()\n\n\n//Delete\np.delete()\n\n```\n\n## Getting Started\n\nTo use ActiveSQLite classes or structures in your target’s source file, first import the `ActiveSQLite` module.\n\n``` swift\nimport ActiveSQLite\n```\n\n\n### Connecting to a Database\n\n``` swift\nASConfigration.setDefaultDB(path:\"db file path\", name: \"default db name\")\n\n//If you want a other db\nASConfigration.setDB(path: \"other db file path\", name: \"other db name\")\n\n```\nYou must set default db path.\n\n\n## Building Type-Safe SQL\n\n| ActiveSQLite\u003cbr /\u003eSwift Type    | SQLite.swift\u003cbr /\u003eSwift Type    | SQLite\u003cbr /\u003e SQLite Type      | SQLite Default Value\u003cbr /\u003e If not use optionl property |\n| --------------- | --------------- | ----------- | ---------- |\n| `NSNumber `     | `Int64`         | `INTEGER`   | `0`|\n| `NSNumber `     | `Double`        | `REAL`      |`0.0`|\n| `String`        | `String`        | `TEXT`      |`\"\"`|\n| `nil`           | `nil`           | `NULL`      |`NULL`|\n|                 | `SQLite.Blob`   | `BLOB`      ||\n| `NSDate`        | `Int64`         | `INTEGER`   |`0`|\n\n\n\nThe NSNumber Type maps with two SQLite.swift's Swift Type. they are Int64 ans Double. The default type is Int64. You can override doubleTypes() function of ASModel to mark properties are Double Type.\n\n``` swift\nclass Product:ASModel{\n\n    var name:String = \"\"\n    var price:NSNumber = NSNumber(value:0.0)\n    var desc:String?\n    var publish_date:NSDate?\n\n  override func doubleTypes() -\u003e [String]{\n      return [\"price\"]\n  }\n  \n}\n```\n\n\nActiviteSQLite map NSDate to Int64 of SQLite.swift. You can map NSDate to String by looking [Custom Types of Documentaion](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#custom-types) of SQLite.swift\n\n\n## Creating a Table\n\nActiveSQLite auto create table and add \"id\". The create code looks like below:\n\n``` swift\ntry db.run(products.create { t in      \n    t.column(id, primaryKey: true)\n    t.column(Expression\u003cNSDate\u003e(\"created_at\"), defaultValue: NSDate(timeIntervalSince1970: 0))\t\n    t.column(Expression\u003cNSDate\u003e(\"updated_at\"), defaultValue: NSDate(timeIntervalSince1970: 0))\t\n    t.column(...)  \n\n})                             \n\n// CREATE TABLE \"Products\" (\n//\t\t\"id\" INTEGER PRIMARY KEY NOT NULL,\n//\t\tcreated_at INTEGER DEFAULT (0),\n//\t\tcreated_at INTEGER DEFAULT (0),\n//     ...\n//\t)\n  \n```\nThe unit of \"created\\_at\" and \"updated\\_at\" columns is ms.\n\n### From ActiveSQLite0.4.0 to 0.4.1\n\nActiveSQLite0.4.0 can use 3 types to define property: T, T!, T?.\u003cbr\u003e\nActiveSQLite0.4.1 use 2 types to define property: T, T?.\n\n| type\t\t|  0.4.0    | 0.4.1    |\n| --------------- | --------------- | ----------- |\n| `T `    | `not nil`        | `not nil`   |\n| `T! `   | `not nil`        | `can be nil. use T? replace`|\n| `T?`    | `can be nil`     | `can be nil`|\n| `pirmary key id` | `is T! type`\t|` is T? type.`|\n\nIf you want find the db column default value to see the first table in this document.\n\n\n### Mapper\nYou can custom name of table, names of column and prevent save some properties into database.\n\n#### 1. DB name.\nIf you use one db, only setDefaultDB(path:name:),, you needn't do anything. If you set you table in other db, you must override dbName.\n\n``` swift\n\nASConfigration.setDefaultDB(path:\"db file path\", name: \"default db name\")\nASConfigration.setDB(path: \"other db file path\", name: \"other db name\")\n\noverride class var dbName:String?{\n    return \"other db name\"\n}\n```\n\n#### 2. Table name.\n\nDefault table name is same with class name, you needn't do anything. If you want use different name ,you must override nameOfTable.\n\n``` swift\n// Set table name to \"ProductTable\"\noverride class var nameOfTable: String{\n    return \"ProductTable\"\n}\n```\n\n#### 3. Column name.\n\nDefault column name is same with properity name, you needn't do anything. If you want use different name, you must override mapper().\n\n``` swift\noverride func mapper() -\u003e [String:String]{\n    return [\"property_name\":\"column_name\"];\n}\n```\n\nIf you let primary key is not \"id\",use like this:\n\n``` swift\noverride class var PRIMARY_KEY:String{\n    return \"_id\"\n}\n    \noverride func mapper() -\u003e [String:String]{\n    return [\"id\":\"_id\"]\n}\n``` \n\n\n#### 4. Transient properties.\n\nTransent properitird have not been saved into database.\n\n``` swift\noverride class func transientTypess() -\u003e [String]{\n    return [\"isSelected\"]\n}\n\n```\nActiveSQLite can only save properities in (String,NSNumber,NSDate) into database. The properities without in these types are not be saved into database, they are transent properities.\n\n#### 5. Auto create \"created\\_at\" and \"updated\\_at\" columns. \n\nJust override isSaveDefaulttimestamp, don't do anything, the super class ASModel already define \"created\\_at\" and \"updated\\_at\" properies.\n\n```swift\n\noverride class var isSaveDefaulttimestamp:Bool{\n        return true\n}\n    \n```\n\n### Table constraints\nIf you want custom columns by yourself, you just set model implements CreateColumnsProtocol, and comfirm createColumns function. Then the ActiveSQLite will not auto create columns. Make sure the properties' names of model mapping the columns'.\n\n```swift\n\nclass Users:ASModel,CreateColumnsProtocol{\n    var name:String = \"\"\n    var email:String = \"\"\n    var age:Int?\n   \n    func createColumns(t: TableBuilder) {\n        t.column(Expression\u003cNSNumber\u003e(\"id\"), primaryKey: true)\n        t.column(Expression\u003cString\u003e(\"name\"),defaultValue:\"Anonymous\")\n        t.column(Expression\u003cString\u003e(\"email\"), , check: email.like(\"%@%\"))\n    }\n}\n```\nfind more infomations to look up [table constraints document](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#table-constraints) of SQLite.swift.\n\n## Inserting Rows\nThere are 3 functions used for insert rows. they are\n\nInsert one.\n\n```swift\nfunc insert()throws ;\n```\n\nInsert more.\n\n```swift\nclass func insertBatch(models:[ASModel])throws ;\n\n```\n\nSave method.\n\nInsert or Update. Insert if id == nil. Update if id != nil.\n\n```swift\nfunc save() throws;\n```\n\neg:\n\n```swift\nlet u = Users()\nu.name = \"Kevin\"\ntry! u.save()\n                \nvar products = [Product]()\nfor i in 1 ..\u003c 8 {\n    let p = Product()\n    p.name = \"iPhone-\\(i)\"\n    p.price = NSNumber(value:i)\n    products.append(p)\n}\n                \ntry! Product.insertBatch(models: products)\n\n```\nFor more to see source code or example of ActiveSQLite, also look up document [Inserting Rows document](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#inserting-rows) of SQLite.swift.\n\n## Updateing Rows\nThere 3 strategies for update.\n\n### 1. Update by attribute.\n\nFirst modefiy attribute of model，and then save() or update() or updateBatch().\n\t\n```swift\np.name = \"zhoukai\"\np.save()\n\n```\n\t\n### 2. Update by String:Value.\n\n```swift\n//Update one\nu.update(\"name\",value:\"3ds\")\nu.update([\"name\":\"3ds\",\"price\":NSNumber(value:199)])\n\n\n//Update more\n\nProduct.update([\"name\": \"3ds\",\"price\":NSNumber(value:199)], where: [\"id\": NSNumber(1)])\n\n```\n\n### 2. Update by Setter.\n\nUpdate one Product object to database. \n\n```swift\n//Update one\np.update([Product.price \u003c- NSNumber(value:199))\n\n//Update more\nProduct.update([Product.price \u003c- NSNumber(value:199), where: Product.name == \"3ds\")\n```\n\nFor more to see source code and example of ActiveSQLite, also look up document [Updating Rows document](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#updating-rows) , [Setters document](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#setters) of SQLite.swift.\n\n\n## Selecting Rows\n\nYou can use findFirst to find one row, use findAll to find more rows.\n\nThe methods that prefix name is \"find\" are class method.\n\n#### 1.Find by attribute.\n\n```swift\nlet p = Product.findFirst(\"name\",value:\"iWatch\")\n\nlet ps = Product.findAll(\"name\",value:\"iWatch\",orders:[\"price\",false])\n\n```\n\n#### 2.Find by Expression.\n\n```swift\nlet id = Expression\u003cNSNumber\u003e(\"id\")\nlet name = Expression\u003cString\u003e(\"name\")\n\nlet arr = Product.findAll(name == \"iWatch\")\n\nlet ps = Product.findAll(id \u003e NSNumber(value:100), orders: [Product.id.asc])\n\n```\n\n### Chainable Query\nchainable query style methods are property method.\n\n```swift\nlet products = Product().where(Expression\u003cNSNumber\u003e(\"code\") \u003e 3)\n                                .order(Product.code)\n                                .limit(5)\n                                .run()\n\n```\nDon't forget excute run().\n\nmore complex queries to see source code and example of ActiveSQLite.\nLook documents [Building Complex Queries](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#building-complex-queries) of SQLite.swift\n\n## Expression\nSQLite.swift use Expression replece 'where' SQL when you execute update and select SQLs.\nComplex Expression to look for [filtering-rows](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#filtering-rows)\n\n## Deleting Rows\n\n```swift\n//1. Delete one row\ntry? product.delete()\n\n//2. Delete all rows\ntry? Product.deleteAll()\n\n//3. Delete by Expression and chains.\ntry? Product().where(Expression\u003cNSNumber\u003e(\"code\") \u003e 3)\n                                .runDelete()\n\n```\n\n## Transactions\nI suggest that you should put all insert, update, delete and alter tables codes into ActiveSQLite.save block. One block is a transaction.\n\n```swift\n ActiveSQLite.save({ \n\n                var products = [Product]()\n                for i in 0 ..\u003c 3 {\n                    let p = Product()\n                    p.name = \"iPhone-\\(i)\"\n                    p.price = NSNumber(value:i)\n                    products.append(p)\n                }\n                try Product.insertBatch(models: products)\n                \n\n                let u = Users()\n                u.name = \"Kevin\"\n                try u.save()\n                \n\n            }, completion: { (error) in\n                \n                if error != nil {\n                    debugPrint(\"transtion failed \\(error)\")\n                }else{\n                    debugPrint(\"transtion success\")\n                }\n\n            })\n\n```\n\n## Asynichronous\nActiveSQLite.saveAsync also contains one transcation function.\n\n```swift\n ActiveSQLite.saveAsync({ \n\t\t\t.......\n\n            }, completion: { (error) in\n                ......\n            })\n```\n## Altering the Schema\n### Renaming Tables and Adding Columns\n\n#### Step 1.You must change model use new columns and new table name.\n\n```swift\nclass Product{\n\tvar name:String!\n\t\n\tvar newColumn:String!\n\toverride class var nameOfTable: String{\n    \treturn \"newTableName\"\n\t}\n\t\n}\n```\n\n#### Step 2. Execute alter table sql when db version update.\n\n```swift\nlet db = DBConnection.sharedConnection.db\n            if db.userVersion == 0 {\n                ActiveSQLite.saveAsync({\n                    try Product.renameTable(oldName:\"oldTableName\",newName:\"newTableName\")\n                    try Product.addColumn([\"newColumn\"])\n                    \n                }, completion: { (error) in\n                    if error == nil {\n                    \n                    \tdb.userVersion = 1\n                    }\n                })\n                \n            }             \n\n```\nmore to look [Altering the Schema](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#altering-the-schema) of SQLite.swift\n\n### Indexes\n\n```swift\n\tlet name = Expression\u003cString\u003e(\"name\")\n\tProduct.createIndex(name)\n\tProduct.dropIndex(name)\n```\nmore to see [Indexes of SQLite.swift Document](https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#indexes)\n\n### Dropping Tables\n```swift\nProduct.dropTable()\n```\n\n## Logging\nThere are 4 log levels: debug,info,warn,error.\nThe default log level is info. Setting log level like this:\n\n```swift\n//1. Set log level\nASConfigration.logLevel = .debug\n\n//2. Set db path\nASConfigration.dbPath = \"...\"\n```\nMake sure setting log level before setting database path.\n\n\n## Requirements\n- iOS 8.0+  \n- Xcode 10.2\n- Swift 5\n\n## Installation\n\n### Cocoapods\n\nActiveSQLite is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod \"ActiveSQLite\"\n```\n\n\n## Author\n\nKevin Zhou\n\n- Email me: \u003cwumingapie@gmail.com\u003e\n- Contact me on **Facebook**: [**wumingapie**](https://www.facebook.com/wumingapie)\n- Contact me on **WeChat\u0026QQ**: 358545592\n\n## License\n\nActiveSQLite is available under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinzhourafael%2Factivesqlite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevinzhourafael%2Factivesqlite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinzhourafael%2Factivesqlite/lists"}