enesefuu
enesefuu

Reputation: 409

Better approach to querying sqlite database in swift

I'm working on a word game and have bundled a complete list of english words using a sqlite database. I'm trying to find the best way to search the database for a given string to determine if it's a word.

At this point I can get the whole database out into an array:

func fetchWords() {
    if let managedObjectContext = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext {

        let wordsFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "EnglishWord")

        do {
            englishWords = try managedObjectContext.fetch(wordsFetch) as! [EnglishWord]

            print(englishWords[123323].word)
            //Prints "injustices"

            } catch {
                //error handling
            }
        }
    }

Now. What I really want to do is pass in a given string and see if it exists as a word in my database. I have a clunky solution with predicates, e.g:

func fetchWordsToArray() {
        if let managedObjectContext = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext {

            let wordsFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "EnglishWord")

            let searchWord = ["dastardly"]
            let searchPredicate = NSPredicate(format: "word = %@", argumentArray: searchWord)

            do {
                englishWords = try managedObjectContext.fetch(wordsFetch) as! [EnglishWord]

                let resultFilteredByPredicate = (englishWords as NSArray).filtered(using: predicate)
                print(resultFilteredByPredicate)

            } catch {
                //error handling
            }
        }

    }

But in order to use the filtered function I have to convert to an NSArray which means I can't work with the results directly (e.g. get resultFilteredByPredicate.word).

Also it feels like I'm probably going about this all the wrong way. Since everything has to go into an array first, I must be losing a lot of the value of using an sqlite database in the first place.

Any suggested approaches for better working with the database?

Many thanks in advance for any help!

Upvotes: 3

Views: 271

Answers (1)

CL.
CL.

Reputation: 180040

To make the database do the filtering (which could then be optimized automatically with an index), put a predicate on the original fetch request:

    let formatRequest : NSFetchRequest<Word> = Word.fetchRequest()
    fetchRequest.predicate = NSPredicate(format: "word == %@", searchWord)
    let fetchedResults = try context.fetch(fetchRequest) as! [Word]

But Core Data is a framework to manage your objects. If you decide that your words are not objects but just values, you could replace Core Data with some other library that does SQL directly, and execute an SQL query instead:

SELECT * FROM EnglishWord WHERE word = ?

Upvotes: 1

Related Questions