1

just wondering if it is possible to cancel or stop a select statement?

I have an application with a sap ultralite database. Database connections and statements are handled within a singleton.

I have a ViewController where I start a heavy READ-operation in the background which sometimes takes up to 2-3s. At the same ViewController, you can change some values and save it with a WRITE-operation, which dismisses the ViewController.

My problem is, if I'm really fast and/or the READ-operation very slow, my ViewController isn't dismissed, because the WRITE operation is waiting for the end of the READ-operation. So the UI freezes for a couple of seconds.

Either thanks to my google search skills or to the poor ultralite documentation, does anyone know, how can I cancel a current ongoing SELECT-statement? (Result of isn't important anymore, because View will be dismissed) Or how can I allow multiple statements at the same time? The READ and WRITE operations working with different tables if that's important

EDIT: (Summarize questions)

  1. Is it possible to READ and WRITE at the same time with ultralite?
  2. If not, are there any other solutions? (At the moment we testing to duplicate the database)

UPDATE (detailed): Well, we found a work-around, but this doesn't answer the question.

We have an application with a ShoppingCard ListView (items are stored in the ultralite db). From this View you can change items (change date of shipping, number of amount...) within a Freeform-ViewController which shows some statistic data.

The statistic is the heavy READ operation, which sometimes takes up to five seconds. So if you for example change the amount of the items and press the DONE button, the Freeform-ViewController starts the WRITE-operation (UPDATE), gets dismissed and the ShoppingCard is updated (again READ to the database to get changes).

The last point was the bad thing, but we implemented a completion-handler for the FreeformVC, which updates just the one item instead of READ the whole shopping card from database. This seems to work, however, it is not the best solution. If you click really fast, you sometimes feel the delay if you want to read from the database again, so the question remains....

longi
  • 11,104
  • 10
  • 55
  • 89
  • 1
    You can put your read/write operation on a background queue so your UI stays responsive. You could use Grand Central Dispatch (`dispatch_async` to a background queue, and then back to the main queue when you're done reading/writing) or `NSOperationQueue`. Just make sure your database class is thread-safe. – Aaron Brager May 26 '14 at 08:05
  • @AaronBrager: read/write operations are in the background. the problem occurs, if `READ` is taking too long, so the second `WRITE` statement has to wait, till the first one is ready (<- this causes `UI` to freeze) – longi May 26 '14 at 08:17
  • If the `WRITE` statement is in the background, then it shouldn't cause the UI to freeze. What's blocking the main thread? – Aaron Brager May 26 '14 at 17:05
  • @AaronBrager: hi aaron, just updated my question. you`re right, background-queue shouldn't block the UI. our problem occurs, because we sometimes wanted to read from the db, but the db is blocked from some operation which are still running in the background. and we don t want the user to wait for a couple of seconds, because the database is still reading some values which are not shown in the UI anymore.. – longi May 27 '14 at 12:22
  • If you use NSOperationQueue, you can put each piece of work in an NSOperation subclass. You can check if `cancel` has been called on the operation and abort any remaining work. – Aaron Brager May 27 '14 at 15:14

1 Answers1

0

First of all Move your Database querying code to another queue (this is a good practice)

Solution is: Start queueing your database operations. This solutions is very easy, the trick is to dispatch your database queries to another queue

// Your read operation
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        // Query here
        // ....
        // Move back to Main queue
        dispatch_async(dispatch_get_main_queue(), ^{
           // Update UI
        });
    });

After this your write operations do the same thing

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    // Write operation
    // ....
});

This solution will not cancel read operation, but UI will not freeze anymore (ViewController will dismiss, but the operations will keep running until they finish).

Another possible way: As the ultralite database is not documented... I think one of possible ways is to destroy and create the manager instance (modifying your singleton class to non-singleton), if this will not crash, it will cancel the running operation.

Another possible way: To use NSOperations, and try to cancel operation... maybe "ultralite" will check canceled state, and will stop the query.

l0gg3r
  • 8,864
  • 3
  • 26
  • 46