stephencelis / SQLite.swift

A type-safe, Swift-language layer over SQLite3.
MIT License
9.65k stars 1.56k forks source link

Custom type NSDate: EXC_BAD_INSTRUCTION #186

Open lukescott opened 9 years ago

lukescott commented 9 years ago

I added the following to my project:

extension NSDate: SQLite.Value {
    public class var declaredDatatype: String {
        return Int.declaredDatatype
    }
    public class func fromDatatypeValue(intValue: Int) -> NSDate {
        return self(timeIntervalSince1970: NSTimeInterval(intValue))
    }
    public var datatypeValue: Int {
        return Int(timeIntervalSince1970)
    }
}

And when I do row.get(Expression<NSDate>("lastUpdated")) I get the following:

screen shot 2015-08-25 at 3 12 07 pm

fromDatatypeValue is not being called.

I'm using the carthage branch (which I forked to change target from iOS 8.3 to 8.0). This is happening in simulator.

Any idea what I'm doing wrong here?

stephencelis commented 9 years ago

Is there an error message printed to the console? Do you have the exception breakpoint enabled?

lukescott commented 9 years ago

No error message in the console, and I do have an exception breakpoint set, but that doesn't seem to make a difference. The $swift.type's are empty, and when I try to expand self Xcode crashes.

lukescott commented 9 years ago

While this doesn't work

row.get(Expression<NSDate>("lastUpdated"))

This does:

NSDate(timeIntervalSince1970:NSTimeInterval(row[Expression<Int>("lastUpdated")]))

Insert works though:

table.insert(
    Expression<NSDate>("lastUpdated") <- date
)
lukescott commented 9 years ago

Ok, so I added SQLite to my project directly and I set a breakpoint on:

func valueAtIndex(idx: Int) -> V? {
    if let value = values[idx] as? V.Datatype { return (V.fromDatatypeValue(value) as! V) }
    return nil
}

And this is what I get:

screen shot 2015-08-25 at 4 58 55 pm
lukescott commented 9 years ago

@stephencelis I figured it out... this works (note: Int64 vs Int):

extension NSDate: SQLite.Value {
    public class var declaredDatatype: String {
        return Int64.declaredDatatype
    }
    public class func fromDatatypeValue(intValue: Int64) -> NSDate {
        return self(timeIntervalSince1970: NSTimeInterval(intValue))
    }
    public var datatypeValue: Int64 {
        return Int64(timeIntervalSince1970)
    }
}

So... it looks like the documentation needs to be updated.

Or maybe when the types don't match instead of returning nil indicate an error like: "Unknown Type: Custom types must use String, Int64, or Blob".

stephencelis commented 9 years ago

Thanks for the sleuthing! These things should cascade, so this looks like a bug related to Int being a first-class Binding. I'll try to come up with a solution.