SwiftData icon indicating copy to clipboard operation
SwiftData copied to clipboard

Check return value of transaction closure

Open eriktelepovsky opened this issue 10 years ago • 6 comments

Hi,

public static func transaction(transactionClosure: ()->Bool) -> Int? returns an Int with the error code, or nil if there was no error committing or rolling back the transaction.

But is it possible to check somehow if the transaction was committed or rollbacked?

eriktelepovsky avatar Oct 20 '14 15:10 eriktelepovsky

Something like this:

/**
    Execute commands within a single exclusive transaction

    ...

    :returns:
        - Bool with true, if transaction was commited, false otherwise
        - An Int with the error code, or nil if there was no error committing or rolling back the transaction
*/
public static func betterTransaction(transactionClosure: ()->Bool) -> (Bool, Int?) {

    // create result variable
    var commited: Bool = false

    ...

    // execute the transaction closure
    if transactionClosure() {
        if let err = SQLiteDB.sharedInstance.commitTransaction() {
            error = err
        } else {
            commited = true
        }
    } else {
        if let err = SQLiteDB.sharedInstance.rollbackTransaction() {
            error = err
        }
    }

    ...

    return (commited, error)
}

eriktelepovsky avatar Nov 04 '14 09:11 eriktelepovsky

Thanks for the feedback; I see your point here.

The transactionClosure that you pass to SD.transaction returns true (to commit the transaction) or false (to rollback the transaction). Instead of adding complexity for most people by returning a tuple, I would suggest adding a variable in your program and changing it in your closure like so:

var transactionCommitted = false

let err = SD.transaction {
    // interact with database here

    if youWantToCommit {
        transactionCommitted = true
        return true
    } else {
        return false
    }
}

if err != nil {
    // there was an error 
    // transactionCommitted will tell you if you attempted to commit or rollback the transaction
}

After your call to SD.transaction, the transactionCommitted variable will indicate if the transaction attempted to commit or rollback.

Let me know if you disagree.

ryanfowler avatar Nov 17 '14 04:11 ryanfowler

Hi, thank you for your answer, but I think we misunderstand each other. Your SD.transaction function returns an Int with the error code, or nil if there was no error committing or rolling back the transaction. I need to know if the error code (if any) is from this part of code:

if let err = SQLiteDB.sharedInstance.commitTransaction() {
   error = err
}

or from this:

if let err = SQLiteDB.sharedInstance.rollbackTransaction() {
   error = err
}

Right now I only know if there was or wasn't any error during execution of SD.transaction(), but I don't know when was the error created.

eriktelepovsky avatar Dec 02 '14 18:12 eriktelepovsky

Hi, if I have many rows in my database, how can I choose just the first row? or how can I make sure that I will have only one row? And one more thing- Where can I see the data base? Does it exist anywhere? Thank! Great job!

hadasaOrit avatar Dec 03 '14 20:12 hadasaOrit

@eriktelepovsky Ok, I understand what you mean now ...

I think the most appropriate way to deal with this is to have better error handling. I'm hoping to have an improved version of SwiftData out in a few weeks and will keep this in mind.

ryanfowler avatar Dec 09 '14 00:12 ryanfowler

@hadasaOrit For your first question, all queries will return an Array of SDRow objects. If you'd only like one row, you can just use the first item of the returned Array, or specify in your SQL query that you'd only like one row returned:

SELECT * FROM sample LIMIT 1

The database called 'SwiftData.sqlite' exists in the 'documents' directory of the device.

ryanfowler avatar Dec 09 '14 00:12 ryanfowler