2015-03-15 2 views
3

Я использую SQLite.swift (Branch Swift-1-2) в своем приложении в бета-версии XCode 6.3. Я могу создать базу данных/таблицы и вставить записи в таблицы.Использование переменных в фильтрах в SQLite.swift

Пока все хорошо.

Теперь, когда у меня есть простой сценарий выглядит следующим образом:

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 
} 

На линии прокомментировал \\ <----ERROR!!!, я получаю ошибку во время компиляции: бинарного оператора «==» не может быть применен к операндам типа Выражение < Int64> и Int

Если я использую Int непосредственно на этой линии, это работает нормально. Например.

let candidateFoo = foos.filter(super.id == 3) // No Error! 

Но, если я просто сделать это, он терпит неудачу с такой же ошибкой снова:

var i = 3 
let candidateFoo = foos.filter(super.id == i) // <----ERROR!!! 

Я понимаю, что ошибка, но я не в состоянии решить. Я посмотрел на documentation, но я все еще застрял. Поэтому любая помощь приветствуется.

Update:

Явное объявить переменную как Int64 решает вопрос:

var i:Int64 = 3 
let candidateFoo = foos.filter(super.id == i) // No Error! 

Теперь мне интересно, если я должен изменить свое определение класса, что потребует изменения в нескольких местах код. Также official swift documentation рекомендует использовать Int, если не требуется явный размер.

You should use the word-sized Int type to store integer values, unless you require a type with a specific size or signedness.

Кроме того, документация SQLite.swift гласит:

While Int64 is the basic, raw type (to preserve 64-bit integers on 32-bit platforms), Int and Bool work transparently.

Так я должен использовать в Int64 здесь явно в моем определении класса, поскольку его сопоставлен с БД?

+0

Я думал, что этот ответ может помочь вам http://stackoverflow.com/questions/29054958/why-do-i-have-to-explicitly-unwrap-my-string-in-this-case –

+0

Я не верю, что это проблема. Я понимаю (я думаю!) Разницу между 'id?', 'Id!' И 'id = 3'. См. Мое обновление выше. Даже если я объявляю локальный 'var i = 3' и использую его в' filter() ', я все равно получаю ту же ошибку. – rgamber

ответ

2

Вы сопоставляете свою структуру Foo непосредственно с базовыми типами SQL, поэтому вы должны использовать один и тот же тип в обоих местах. Если вам нужна 64-битная точность на 32-битных устройствах (во избежание переполнения и т. Д.), Вы должны использовать Int64. Если вы не волновались, используйте Int оба места:

var id = Expression<Int>("id") 

If I use an Int directly on that line, then that works fine. Eg.

Это происходит потому, что это на самом деле Int64, который соответствует IntegerLiteralConvertible базовому типу так литерала выводятся (вы можете прочитать больше о буквальных кабриолетах Свифта здесь: http://nshipster.com/swift-literal-convertible/).

So should I be using the Int64 here explicitly in my class definition, since its mapped to a DB?

Имейте в виду, что выражение SQLite.swift слой дает вам гибкость, чтобы сослаться на основных типов столбцов, однако вы хотите (если вы conform it to its Value protocol), так снова: вы можете использовать Int свободно, если это, как вы «обрабатывать значение во всем коде.

Помимо всего этого, когда вы работаете с разными целыми типами в Swift, вы можете использовать их в строках. .,

let candidateFoo = foos.filter(super.id == Int64(foo.id!)) 
+0

Это разъясняет мою точную точку смятения! Спасибо за ответ! – rgamber

Смежные вопросы