EzDev.org

SQLite.swift

A type-safe, Swift-language layer over SQLite3.


SQLite.swift - Cannot subscript a value of type Row. Swift 2

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)

Swift 2 SQLite.swift module reference

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)

SQLite.swift build error "Module file's minimum deployment target is ios8.3 v8.3"

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)

Trying to insert 10000 records sqlite ios swift

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)

Using variables in Filters in SQLite.swift

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)

SQLite Insert is not working in swift

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)

SQLite.swift: Best way to implement model classes representing rows of a given table?

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)

Do I need to "close" a connection in SQLite.swift?

Not sure about whether I should and how to close a Connection in SQLite.swift. Will it cause thread/memory leak?


Source: (StackOverflow)

SQLite API changes proximal to Xcode 6.3 release?

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?

enter image description here

enter image description here


Source: (StackOverflow)

SQLite.swift Module file was created by an older version of compiler

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)

SQLite.swift swift 2 - select all columns of a table with * from in joined tables

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)

Cannot invoke 'insert' with an argument list of type

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)

filtering Tables and put it into an array , some new in Xcode 7?

I've got Xcode 7 but since there are many errors in my old Project, I stuck with one Problem:

xcode 6:

var myData: Array<Row> = []
var my_mData: Array<Row> = []

var m_mitglieder : Query!
var m_firmen : Query!
var stmt_m : Query!
var stmt_f : Query!
var Daten:[String] = []

let m_vorname = Expression<String>("Vorname")
.....

in ViewDidLoad

m_mitglieder = dbFirma["Mitglieder]
stmt = m_mitglieder.select(m_vorname,m_nb......).filter(mnr0 == m_mnr)
myData = Array(stmt)

if Int(myData[0].get(m_nb)) > 0 {
  Daten.append(myData[0].get(m_nb))
}
...

xcode 7:

var myData: Array<Row> = []
var my_mData: Array<Row> = []

let m_mitglieder = Table("Mitglieder")
let m_firmen = Table("firmen")
//var stmt_m : Query!
//var stmt_f : Query!

let m_vorname = Expression<String>("Vorname")
.....

in ViewDidLoad

m_mitglieder = dbFirma["Mitglieder]
let stmt = m_mitglieder.select(m_vorname,m_nb......).filter(mnr0 == m_mnr)
let myData = Array(stmt)  <<<<<ERROR Missing Argument lable 'arrayLiteral:' in call

if Int(myData[0].get(m_nb)) > 0 {
  Daten.append(myData[0].get(m_nb))
}
...

I get the error message : Missing Argument lable 'arrayLiteral:' in call

But when I try to fix it to

myData = Array(arrayLiteral: stmt)    

then I get errors as

Daten.append(myData[0].get(m_nb))  <<<ERROR: Value of type
'ScaleQuerystring>' has no member 'get'

How can I fix this Problem?


Source: (StackOverflow)

Use NSArray in SQLite Statement

I use SQLite.swift and want to replace the question marks in a statement. This can be done for single entries like this:

let stmt = db.prepare("INSERT INTO users (email) VALUES (?)")
for email in ["betty@icloud.com", "cathy@icloud.com"] {
    stmt.run(email)
}

I did not see how I can do the following to use a array like:

var values:[String] = ["test1","test2", "test3"]

in a Statement like:

let stmt = db.prepare("SELECT * from users where email in (?)")

The following does not work:

stmt.run(values)

How do I use an NSArray as an argument for a statement?


Source: (StackOverflow)

Sqlite.swift create dynamic complex queries

I have 1 table with multiple columns. On the app, we are looking forward to add 4 dynamic filters like (cat, size, color,shape).

We know we can create a filter to sqllite like so:

user = user.select(name) 
        .filter((color == "Blue") && (size = "Big") && (cat="a") && (shape="round")) 
        .order(name.asc, name) // ORDER BY "email" DESC, "name"
        .limit(5, offset: 0)

But what happens if a filter, let's say that for color we want to search for all colors. Then,

.filter((color == "?????") && (size = "Big") && (cat="a") && (shape="round"))

Any ideas on how to create dynamic filters for this case?


Source: (StackOverflow)