views:

90

answers:

4

I'm working in a database on vb.net with sqlite wich hosts a gallery and I want expand the search propieties.

This the actual query string:

"SELECT images.*
FROM images 
JOIN nodes 
ON images.id = nodes.image_id 
WHERE tag_id = (SELECT tags.id 
                FROM tags 
                WHERE tag = '" & tagname & "') 
ORDER BY images." & sort & " " & order & ""

But it only can search for only one descriptive tag (tagname) and sort the images and nothing more.

I want to filter the results also for image ext (table = images.ext) or one or more parameter...for example:

If the user search "cars ext:jpg width>500" the the database returns all images wich has the tag "cars", has the extension jpg and are bigger than 500 px width.

Help please D=

+1  A: 

First, this code is dangerous. It's open to SQL Injection attacks. You shouldn't just append string values like that to the query string. Instead, you should use a parameterized query.

In regards to your specific question, you should check the inputs for the search, and based on the inputs, generate the specifc sections of the query, parameterizing them where necessary.

For example, if you have to filter on extensions, then you add a join to the extensions table in the variable holding the join clause, as well as a filter on the joined table in the variable holding the where clause (as well as the appropriate parameter and parameter value).

Then, in the end, you concatenate the parts of the query together (along with the query parameters) and execute it.

casperOne
This code is used in a local database, not in a sql server. It uses sqlite and the user laod the images from his computer, not from internet.
Sein Kraft
@Sein Kraft: It doesn't matter where the code is used, if any part of the tagname, sort, or order parameters relies on user input (even in a derived sense) then you are subject to SQL Injection.
casperOne
Still it's a bad habit to concat query strings. Don't do it, especially not for example code.
Sander Rijken
A: 

If I understand the question correctly, you just want to build up a query string. Have you tried something like this?

SQLcommand.CommandText = "SELECT images.* FROM images JOIN nodes ON images.id = nodes.image_id WHERE tag_id = (SELECT tags.id FROM tags WHERE tag = '" & tagname & "') AND images.Ext = '" & ext & "' AND width > " & width & " ORDER BY images." & sort & " " & order & ""

bglenn
This, like the original question, makes the code susceptible to SQL Injection
Sander Rijken
Of course it's susceptible to Sql Injection. (a) security wasn't part of the question and (b) the op already said it's a local app
bglenn
@bglenn: as a side note, you can use the 101010 button to format your code (or indent by 4 spaces).
Sander Rijken
Thanks for that Sander. I'm new here, will definitely use that.
bglenn
@bglenn: Even if it's a local app, if the user types some text in that includes a quote, either intentionally or accidentally, then the application is either going to do something weird and unexpected, or more likely fail with a confusing error message. There's no good reason to not do it the correct way, using parameters.
Mark Byers
+1  A: 

First of all, if that input is coming in from the user, don't concatenate strings like that, because it's succeptible to SQL Injection

Using SQL Parameters is a way to avoid the injection:

command.CommandText = "SELECT images.* " &_
                      "FROM images " &_
                      "JOIN nodes " &_
                      "ON images.id = nodes.image_id " &_
                      "WHERE tag_id = (SELECT tags.id " &_
                                      "FROM tags " &_
                                      "WHERE tag = @tag)"

You can extend this to:

command.CommandText = "SELECT images.* " &_
                      "FROM images " &_
                      "JOIN nodes " &_
                      "ON images.id = nodes.image_id " &_
                      "WHERE tag_id = (SELECT tags.id " &_
                                      "FROM tags " &_
                                      "WHERE tag = @tag)"

command.Parameters.AddWithValue("@tag", searchTag)


If Not String.IsNullOrEmpty(searchExt) Then
    command.CommandText = command.CommandText & " AND images.ext = @imageExt"
    command.Parameters.AddWithValue("@imageExt", searchExt)
EndIf

If Not String.IsNullOrEmpty(searchWidth) Then
    command.CommandText = command.CommandText & " AND images.width > @imageWidth"
    command.Parameters.AddWithValue("@imageWidth", searchWidth)
EndIf
Sander Rijken
And what happend if the user doesn't input the file ext? i mean if searchExt is null or empty?
Sein Kraft
@Sein Kraft, I edited my answer accordingly
Sander Rijken
Thanks, Sander Rijken.
Sein Kraft
it will probably not fit right in, but you'll get the idea, thanks
Sander Rijken
A: 

Build WHERE clause separately and when add it to your query.

where="1"
if tagname<>"" then where=where & " AND tag='" & tagname & "'"
...
"SELECT images.*
FROM images 
JOIN nodes 
ON images.id = nodes.image_id 
WHERE tag_id = (SELECT tags.id 
                FROM tags 
                WHERE " & where & " ) 
ORDER BY images." & sort & " " & order & ""
Sergey Kornilov