1

Based on SQLite tutorial for Swift (Link), I am able to perform a query successfully as follows (with a raw query):

struct myStruct {
   var value1 = String()
   var value2 = String()
   var value3 = String()
   var value4 = String()
}

do {
   guard let queryResults = try? db.prepare("SELECT value1, value2, value3, value4 FROM table WHERE identifier = 0")
   else {
      print("ERROR")
      return
   }
   //first way to get data (works)
   for row in queryResults {
      let data = myStruct(value1: row[0] as! String, value2: row[1] as! String, value3: "", eventDate: row[2] as! String, value4: row[3] as! String)
      tableViewData.append(data)
   }
   //second way to get data into struct     
   _ = queryResults.map { row in
       let data = myStruct(value1: row[0]! as! String, value2: row[1] as! String, value3: "", eventDate: row[2] as! String, value4: row[3] as! String)
       tableViewData.append(data)
   }
}
catch let ex {
   print("ReadDB error: \(ex)")
}

But, if I change the style of the query as follows:

do {
   let query = myTable.select(value1, value2, value3, value4).where(identifier == 0)
   guard let queryResults = try? db.prepare(query)
   else {
      print("ERROR")
      return
   }
   //does not work
   for row in queryResults {
      let data = myStruct(value1: row[0] as! String, value2: row[1] as! String, value3: "", eventDate: row[2] as! String, value4: row[3] as! String)
      tableViewData.append(data)
   }
   //neither working   
   _ = queryResults.map { row in
       let data = myStruct(value1: row[0]! as! String, value2: row[1] as! String, value3: "", eventDate: row[2] as! String, value4: row[3] as! String)
       tableViewData.append(data)
   }
}
catch let ex {
   print("ReadDB error: \(ex)")
}

I get this error:

Cannot subscript a value of type 'Row' with an index of type 'Int'

Can anyone help me with this?

2

2 Answers 2

2

This is the right way

do {
   let query = myTable.select(value1, value2, value3, value4).where(identifier == 0)
   guard let queryResults = try? db.prepare(query)
   else {
      print("ERROR")
      return
   }
   //option 1
   for row in queryResults {
      let data = myStruct(value1: try row.get(value1), value2: try row.get(value2), value3: try row.get(value3), value4: try row.get(value4))
      tableViewData.append(data)
   }
   //option 2  
   _ = queryResults.map { row in
       let data = myStruct(value1: try row.get(value1), value2: try row.get(value2), value3: try row.get(value3), value4: try row.get(value4))
       tableViewData.append(data)
   }
}
catch let ex {
   print("ReadDB error: \(ex)")
}
Sign up to request clarification or add additional context in comments.

Comments

1

From the tutorial, it seems that something like

//This is from tutorial

let query = users.select(email)           // SELECT "email" FROM "users"
             .filter(name != nil)     // WHERE "name" IS NOT NULL
             .order(email.desc, name) // ORDER BY "email" DESC, "name"
             .limit(5, offset: 1)     // LIMIT 5 OFFSET 1

That .select(item) actually IS the query itself. So, whenever you do

let query = myTable.select(value1, value2, value3, value4).where(identifier == 0) then THIS is the query; you don't need to prepare anything for the db. The person(s) who created this library has tried to make it easier whereas you can just do .select(item) instead of creating a statement and sending it to a db.

Using the example above, you can see that the query selects email, where it is filtered, ordered, and limited. Therefore, for you, query is what you want as queryResult -- I am not sure what that would return... You would be running the result of query on db.prepare(query)...hrm? :P

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.