SQLite.swift
A type-safe, Swift-language layer over SQLite3.
I have only been using xcode for about a month. I have xcode 6 installed and created a project that used the SQLite.swift project by stephencelis from GitHub. All had been running fine and I think I must have inadvertently loaded an Xcode update this morning. I am now on xcode version 6.3. Now when I open my project and perform a build I get the error on a line in one of my units that does "import SQLite". The error message reads: "Module file was created by an older version of compiler". Prior I had 50+ errors in the SQLite source files so I had downloaded the latest zip for SQLite and opened that project and performed a build which worked with no errors. But now if I go back and compile my project I get the error mentioned in subject.
I think I just don't know how to properly use these libraries from GitHub or if this is specific to SQLite.
Any help would be greatly appreciated.
Source: (StackOverflow)
After updating to Xcode 6.3/Swift 1.2 I'm getting thess errors. (.NoCase
can't be found, and .insert
doesn't accept (Setter, Setter)
.
Did something change in the SQLite swift API?
Source: (StackOverflow)
Not sure about whether I should and how to close a Connection in SQLite.swift. Will it cause thread/memory leak?
Source: (StackOverflow)
This method was working while I was using Swift 1.2. But now, I had to update to Xcode and I had to switch my language to Swift 2. This is the method from swift 1.2 which I used well ;
static func findById(idToFind : Int64) -> T? {
let query = table.filter(id == idToFind)
var results: Payment?
if let item = query.first {
results : T = Payment(id: item[id], imageName: item[image], type: item[type], deliveredPriceStr: item[deliveredPrice], orderID: item[orderId])
}
return results
}
Now I modified it for Swift 2 but couldn't manage;
static func findById(idToFind : Int64) -> T? {
let query = table.filter(id == idToFind)
do {
let query = try table.filter(id == idToFind)
let item = try SQLiteDataStore.sharedInstance.SADB.pluck(query)
if try item != nil {
let results : T = Payment(id: item[id], imageName: item[image], type: item[type], deliveredPriceStr: item[deliveredPrice], orderID: item[orderId])
} else {
print("item not found")
}
} catch {
print("delete failed: \(error)")
}
}
return results
}
And I'm getting this error : "Cannot subscript a value of type Row" . My item's data type seems like changed to Row. How can I parse it ? What should I do ?
PS: I'm using swift2 branch.
Source: (StackOverflow)
Since I have updated to Xcode 7 and swift 2, I'm getting this errors:
No type named 'Query' in module 'SQLite'
Use of undeclared type 'Database'
using this code:
let table:SQLite.Query
init(db:Database){
table = db["BucketType"]
}
I'm using the swift2 branch of SQLite.swift, but it looks like my project, it can't find the reference SQLite.swift module.
Also have import SQLite on every file I use SQLite.swift with.
I've tried the manual integration and the cocoa pods, but with the same results.
It was working with Xcode 6.4.
Source: (StackOverflow)
I have upgraded OS X from 10.9 to 10.10 in order to be able to use Xcode 6.3 - current Version is 6.3 (6D570).
When I created my project with Xcode 6.2 I successfully imported SQLite.swift as described in the documentation and everything was working.
After I upgraded to Xcode 6.3 the project cannot be build - I always get the error:
Module file's minimum deployment target is ios8.3 v8.3: /Users/d...
I have tried to set different deployment targets as described in this answer but nothing helps :(
Can somebody help? Thanks in advance
Source: (StackOverflow)
I am trying to insert 10000 records and its taking 45 secs
this is my code
println(NSDate.new())
for index in 0...10000{
countrys.insert(name <- "abc")
//println(index)
}
println(NSDate.new())
is this way to do it?
Source: (StackOverflow)
I am using SQLite.swift (Branch Swift-1-2)
in my app in XCode 6.3 beta.
I am able to create the Database/Tables and insert entries into the tables.
So far so good.
Now when I have a simple scenario as follows:
class Foo {
var id: Int?
var name: String?
/* constructor to create an instance ... */
}
// This is how the table column is defined
var id = Expression<Int64>("id")
// Function to update data in the table
func updateFoo(foo: Foo) -> Int? {
// 'foos' is the table name
let candidateFoo = foos.filter(super.id == foo.id!) //<----ERROR!!!
let (rowsUpdated, statement) = candidateFoo.update(name <- foo.name!)
if let rowsUpdated = rowsUpdated {
println("Succesfully updated \(rowsUpdated) row(s)")
return rowsUpdated
} else if statement.failed {
println("Update failed. Reason: \(statement.reason)")
}
return nil
}
On the line commented \\ <----ERROR!!!
, I get the compile-time error:
Binary operator '==' cannot be applied to operands of type Expression< Int64 > and Int
If I use an Int
directly on that line, then that works fine. Eg.
let candidateFoo = foos.filter(super.id == 3) // No Error!
But, if I simply do this, it fails with the same error again:
var i = 3
let candidateFoo = foos.filter(super.id == i) // <----ERROR!!!
I understand what the error is, but I am not able to resolve it. I looked at the documentation but I am still stuck. So any help is appreciated.
Update:
Explicitly declaring the variable as Int64 solves the issue:
var i:Int64 = 3
let candidateFoo = foos.filter(super.id == i) // No Error!
Now I am wondering if I have to change my class definition, which will require changes at multiple places in the code. Also official swift documentation recommends using Int unless an explicit size is required.
You should use the word-sized Int type to store integer values, unless
you require a type with a specific size or signedness.
Also, the SQLite.swift documentation states that:
While Int64 is the basic, raw type (to preserve 64-bit integers on
32-bit platforms), Int and Bool work transparently.
So should I be using the Int64
here explicitly in my class definition, since its mapped to a DB?
Source: (StackOverflow)
I am trying to insert data from array into my table. If the insert is done I think, its suppose to print it in the console, but it is not. So I tried db.trace(println) and it shows me
SELECT * FROM "formatedData1"
My createDatabase function:
func createDatabase(){
var data = db["formatedData1"]
db.create(table: data, ifNotExists: true){ d in
d.column(type, primaryKey: true)
d.column(ada)
d.column(code)
d.column(name)
d.column(proof)
d.column(size)
d.column(case_size)
d.column(price)
}
for var i = 0; i < self.dataArrayMut.count; ++i{
data.insert(type <- (self.dataArrayMut[i].valueForKey("Type") as! String), ada <- (self.dataArrayMut[i].valueForKey("ADA") as! String), code <- (self.dataArrayMut[i].valueForKey("Code") as! String), name <- (self.dataArrayMut[i].valueForKey("Name") as! String), proof <- (self.dataArrayMut[i].valueForKey("Proof") as! String), size <- (self.dataArrayMut[i].valueForKey("Size") as! String), case_size <- (self.dataArrayMut[i].valueForKey("CaseSize") as! String), price <- (self.dataArrayMut[i].valueForKey("Price") as! String))
}
db.trace(println)
}
Then I tried to run queries on the table to see if the data exists.
1st query:
//Select * From data
let all = Array(data)
println(all.description)
And when I print it I get
[SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row]
2nd Query
//Select name From data where type = rum
let query = data.select(name)
.filter(type == "Rum")
println(query)
And when I print it I get
"formatedData1"
3rd Query
I wanted to print all rows only from two columns.
for datas in data.select(type, name){
println("type: \(data[type]), name: \(data[name])")
}
And It prints
SELECT "Type", "Name" FROM "formatedData1"
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
Sorry for long question but any help would be highly appreciated.
Source: (StackOverflow)
This is only question I've asked (so far) that doesn't need much/any explanation.
I had got as far as this with solving it:
- each class might have an
initialiseTable()
kind of like function which would be called when the DB schema is initialised?
- Static constants in each class for column
Expression<T>
I guess the part I'm pondering about most is filling instances of model classes with Query
results.
As always, thanks in advance for help :)
Link to the awesome SQLite.swift for those who haven't come across it yet.
Update (22/4/15 14:13):
After thinking about it, I'm not sure about storing row data in iVars as it may become tricky to workout saving and updating logistics and overcomplicate things.
However, I still think having model classes to represent rows is a good idea. I think the main benefit of having model classes representing table rows is safety. Knowing that a Query
has column name : Expression<String>
, for example. This is great to have if you start passing Query
instances around between classes
Like I said, I'm not sure if one would really want to start making a class which has iVars for each column to represent rows. If you do that, you could start to get in to ORM land which I feel takes the simplistic beauty of SQLite.swift away. The only benefit that I can think of by keeping iVars for each column would be that you could call refresh()
on an instance which would retrieve the latest data from the DB, and then all other objects pointing to this instance would have the latest data without having to hit the DB theirselves.
Perhaps just having a class that subclasses Query and has a constructor that takes a Database and initialises with the correct table name? Perhaps this could have getters somehow for row columns.
I'm just thinking out loud here trying to give some food for thought. These ideas a pretty immature and young, just thinking about the limitations and benefits in my head of each approach you could take😛. Will come back and add/change more when I've refined the ideas.
Update (24/4/15 09:45):
Perhaps the model classes should just be proxies to the DB tables? Each class having a setter for each field that writes to the DB straight away so that there's no conflict in state as it's always mirroring what's in the DB. But then you wouldn't be able to manage how often you go to the DB that easily? BUT. Are you really changing values that often?
Source: (StackOverflow)
I'm using SQLite.swit (https://github.com/stephencelis/SQLite.swift) to develop an app. I was following the Pod installation guide and can get it running on iOS simulator. However, when I try to install the app on my test device, it shows the error
/Users/.../Build/Products/Debug-iphoneos/Pods/SQLite.framework/Headers/SQLite.h:9:9:
error: 'SQLite/SQLite-Bridging.h' file not found
Is it my way of configuration incorrect? Anyway ran into the same issue as mine?
Source: (StackOverflow)
I use SQLite.swift
I tried the expression:
userTable.filter(contains([1, 2, 3, 4, 5], entryId))
from the example. But I got the following error:
Cannot find an overload for 'contains' that accepts an argument list of type '([Int], Expression<String>)'
How can I make this work?
Source: (StackOverflow)
I have downloaded SQLite.swift and get this error:
Playground execution failed: /var/folders/43/nc3kf6y17dbfdn14crfmcdjh0000gn/T/./lldb/2060/playground2.swift:1:8: error: no such module 'SQLite'
import SQLite
I also note that SQLite.swift has a reference to sqlcipher.xcodeproj. Do I need to include this too?
Even with the playground in SQLite I get the same error.
I am using Xcode 7.1 Beta with the c9d3082 commit of SQLite.swift
Have followed your instructions precisely.
Many thanks
Now solved. Here is the answer:
1) Make sure "Framework Search Paths" in Build Settings for your project is set to the workspace where SQLite is loaded. In my system I had them in the same workspace
2) Get rid of the additional info from Per-configuration Build Products Path. My just says: "$(BUILD_DIR)/$(CONFIGURATION)"
3. IN SQLite, Clean then rebuild. Then run Tests. Make sure SQLite.framework is not coloured red under Products in SQLite.xcodeproj
4. Then follow Stephen's steps 1 to 4.
5. I am using Xcode 7.2 Beta
Source: (StackOverflow)
I am trying to select all columns from a table in a joined SQLite.swift table statement with the help of the select function, but I always get the following error:
Cannot invoke 'select' with an argument list of type '(Expression<Void>)'
Here is a demo code producing the error:
let messageId = Expression<String>("id")
let messageContent = Expression<String>("content")
let messageGroupId = Expression<String>("group_id")
let groupId = Expression<String>("id")
let groupName = Expression<String>("name")
if let db = try? Connection()
{
let messageTable = Table("message")
let groupTable = Table("group")
try! db.run(messageTable.create() { t in
t.column(messageId, primaryKey: true)
t.column(messageContent)
t.column(messageGroupId)
})
try! db.run(groupTable.create() { t in
t.column(groupId, primaryKey: true)
t.column(groupName)
})
let query = messageTable
.join(groupTable, on: messageTable[messageGroupId] == groupTable[groupId])
.filter(messageTable[messageGroupId] == "SOME GROUP ID")
.select(messageTable[*]) // THIS SELECT IS CAUSING AN ERROR - WHAT IS WRONG?
}
The last call of the select function is always causing an error when I try to use the STAR (all fields of a table). Is there any way I can use the star operator and not list all of the fields separately?
I am using Xcode 7.0.1, maybe this is fixed in 7.1 with swift 2.1?
Source: (StackOverflow)
The code to insert records into a table was working fine before the latest update, but now is throwing up this error so I was wondering what I was doing wrong.
Example code for record insert:
Recipes.insert(Title <- "Chocolate Cake", Description <- "Rich and moist", CookTime <- 20, PictureURL <- "http://w2.fnstatic.co.uk/sites/default/files/pictures/articles/omg-chocolate-cake-7.jpg", VideoURL <- "https://www.youtube.com/watch?v=ZqMqTB7RSjo", Instructions <- "Prepare ingredients into bowl. Whisk for 20 mins, and pour into cake moulding tin. Place in oven at 200C for 15 minutes. Allow 10 mins to cool before icing with chocolate frosting.", Category <- "Desert", Ingredients <- "50g Flour, 200ml Milk, 2 large eggs, Choclate frosting", Favourited <- false)
Example for database setup:
import Foundation
import SQLite
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as! String
let db = Database("\(path)/databasetest.sqlite3")
let Recipes = db["Recipes"]
let RecipeID = Expression<Int>("RecipeID")
let Title = Expression<String>("Title")
let Description = Expression<String>("Description")
let CookTime = Expression<Int>("CookTime")
let PictureURL = Expression<String>("PictureURL")
let VideoURL = Expression<String>("VideoURL")
let Instructions = Expression<String>("Instructions")
let Category = Expression<String>("Category")
let Ingredients = Expression<String>("Ingredients")
let Favourited = Expression<Bool>("Favourited")
func TableSetup() {
db.create(table: Recipes, ifNotExists: true) { t in
t.column(RecipeID, primaryKey: true)
t.column(Title)
t.column(Description)
t.column(CookTime)
t.column(PictureURL)
t.column(VideoURL)
t.column(Instructions)
t.column(Category)
t.column(Ingredients)
t.column(Favourited, defaultValue: false)
}
I am using stephencelis' SQLite.swift project. https://github.com/stephencelis/SQLite.swift
Source: (StackOverflow)