This is already partially discussed in this related question, but I'll try here to address more specifically some of the issues you rise.
Generally speaking, Grover's algorithm rests upon the assumption that one is able to perform a querying operation of the form $$|i\rangle\mapsto(-1)^{f(x_i)}|i\rangle,$$ where $i$ is the index in the database, and $x_i$ whatever information the database attaches to $i$.
You can think of $f(x_i)$ as "asking a question about $x_i$". For example, this question may be "is $x_i$ a prime number?", or "does $x_i$ have property $P$?", where $P$ could mean "being red".
It is important to note that $f$ could be asking a question which does not fully characterize $x_i$. This means that after I run the algorithm and retrieve $i$, and thus $x_i$ with it, I also gain knowledge which was not used to build the oracle.
However, in many proof of principle implementations of Grover's algorithm, like the one you show, this is not the case. Indeed, in these demonstrationdemonstrations the question that is being asked is "trivial", in the sense that $x_i=i$, and the question is of the form "is $x_i$ equal to 3?".
In such a case, the algorithm is indeed not particularly useful in that the answer has to be hardcoded into the oracle, but this isneeds not be the case in general.