|
|
|
|
|
by zopa
5107 days ago
|
|
> "Right now I see no difference between the good and bad" You're building a new query string each time you create a Query object, and concatenating the string onto that. With that approach, each time you build a Query object you have a fresh opportunity to mess up. So you're right that there's no difference between your to cases. Let's drop my off-the-cuff example and look at how a real library, postgresql-simple, handles the issue: query :: (ToRow q, FromRow r) => Connection -> Query -> q -> IO [r]
Usage example query conn "select x from users where name like ?" (Only username)
Do you see the difference? Instead of sticking the username into the SQL query by hand, we use a query function that takes three parameters: a database handle, a Query with a '?' character, and a thing you want to use in the query. The function takes care of properly escaping the username during interpolation. (The "Only" is just a wrapper to make sure we're handing in a datatype we can query with.)Notice that because Query is a distinct type from String, just doing query conn ("select x from userse where name like" ++ username)
doesn't typecheck. Bad Programmer would have a hard time screwing this up.The full documentation for postgresql-simple is here: http://hackage.haskell.org/packages/archive/postgresql-simpl... |
|
query conn ("select x from users where name like #{username}")
How do type-safe languages prevent this?