>
> Unless I'm misunderstanding something, that kind of string concatenation 
> looks dangerous to me.


This approach may be error prone so testing is important but I believe the 
database/sql placeholders avoid any SQL injection. Here the caller also has 
responsibility to validate the input (such as to avoid a person making 
moves for others). I wouldn't call it flexible in an instantly readable 
sense but it's not too bad to work with.

Matt

On Sunday, March 4, 2018 at 12:55:43 AM UTC-6, Benjamin Thomas wrote:
>
> Unless I'm misunderstanding something, that kind of string concatenation 
> looks dangerous to me.
>
> I'v been doing a bit of digging...
>
> Turns out there is a DSL that looks like what I'm looking for: the Lucene 
> query syntax <https://lucene.apache.org/core/3_6_0/queryparsersyntax.html>
> .
>
> Some variant of it is even specifically designed to be opened up to direct 
> user input it seems.
>
> However I don't really want to duplicate data to a search DB like 
> elasticsearch (or bleve), as it seems overkill for the size of the dataset, 
> and SQL will be perfectly fine for query performance.
>
> I also stumbled upon this interesting article: 
> http://www.recursion.org/query-parser/
>
> The author advocates building a custom parser, for domain flexibility, 
> performance and security, basically what I'm looking for it seems.
>
> Although this is ruby code, and the queried DB is elasticsearch, and not 
> an SQL database, the same concepts apply.
>
> I've looked around, but haven't found any library that would take a lucene 
> like query syntax as input, and generate some kind of SQL abstraction as 
> output.
>
>
>
> 2018-03-03 22:46 GMT+01:00 <matthe...@gmail.com <javascript:>>:
>
>> Mapping a subset DSL to SQL doesn’t sound too difficult since SQL already 
>> has those boolean expressions and such. The database/sql library uses 
>> context for cancellation, so queries that take too long could be cancelled 
>> by a timer goroutine.
>>
>> One thing for me that would be helped by a library is keeping track of 
>> the argument placeholders ($1 $2 $3) and their indexing in the slice input 
>> to database/sql for the variadic part. Adding FOR UPDATE sometimes is also 
>> kind of ugly.
>>
>> Here’s a case where I dynamically constructed a query: 
>> https://github.com/pciet/wichess/blob/master/game.go#L209
>>
>> Matt
>>
>> On Friday, March 2, 2018 at 12:38:23 PM UTC-6, Benjamin Thomas wrote:
>>>
>>> I believe correctly used database/sql (with the argument placeholders) 
>>>> protects against SQL injection
>>>>
>>>
>>> Yeah I badly explained this, an SQL builder solves security *AND* 
>>> flexibility for me. Standard database/sql placeholders are too painful when 
>>> the user params are too complex, and I can't just pass around SQL fragments.
>>>
>>> It sounds like you are reinventing SQL. Why do you need a DSL?
>>>>
>>>
>>> Yes, in a way SQL would be awesome, but way too powerful (and too 
>>> verbose). You can potentially access data from other tables, update/delete 
>>> data, etc.
>>>
>>> And how could you pass along raw SQL securely?
>>>
>>> I guess restricting data access could solve some issues. But let's say 
>>> I'd like to give access to a regex filter for some columns, but not others 
>>> (for performance reasons). Not sure if this would be possible at all via db 
>>> policies.
>>>
>>> I guess I'm looking for a "dumbed down" query language.
>>>
>>> In other words, as a programmer I've always been frustrated by search 
>>> forms I've developed. As a user, same thing, I always find them too 
>>> restrictive.
>>>
>>> I feel access to a DSL could be interesting for a power user, rather 
>>> than trying to anticipate every combination of search params a user would 
>>> want to perform. 
>>>
>>> Look at github for example, their advanced search form is interesting, 
>>> and love how readable the url can be: 
>>> https://github.com/search?q=language:Go+stars:<100+forks:>500
>>>
>>> However every params seems to be ANDed, so let's say you'd like to 
>>> search golang repos with less than 100 stars OR forks greater than 500, you 
>>> can't do it.
>>>
>>> Also if you pass invalid input, you seem to get garbage 
>>> : /search?q=language:whatever+stars:<100, so I feel that overall the user 
>>> experience is not that great.
>>>
>>> You see my point?
>>>  
>>>
>>> Le vendredi 2 mars 2018 15:11:19 UTC+1, matthe...@gmail.com a écrit :
>>>>
>>>> To prevent SQL injection and for flexibility, I'm set on using an sql 
>>>>> builder library.
>>>>
>>>>
>>>> I believe correctly used database/sql (with the argument placeholders) 
>>>> protects against SQL injection.
>>>>
>>>> There’s a query builder for postgres with MIT license posted here a few 
>>>> days ago: 
>>>> https://groups.google.com/forum/#!topic/golang-nuts/Mtqvr1N1zAI
>>>>
>>>> Otherwise strings.Builder (or bytes.Buffer pre-1.10), + string 
>>>> concatenation, or fmt.Sprintf can do it.
>>>>
>>>> ## First, create a solid CLI app. Then port it to the web via a JSON 
>>>>> API, that would simply consume the query string.
>>>>
>>>>
>>>> In Go this might be best done as a non-main package with a cmd folder 
>>>> that has a folder for the server and a folder for the CLI app.
>>>>
>>>> I'm thinking of implementing a lexer/parser for this, but first I'd 
>>>>> like to make sure I'm not going to reinvent the wheel :)
>>>>
>>>>
>>>> It sounds like you are reinventing SQL. Why do you need a DSL?
>>>>
>>>> Matt
>>>>
>>>> On Friday, March 2, 2018 at 7:45:19 AM UTC-6, Benjamin Thomas wrote:
>>>>>
>>>>> Hello gophers,
>>>>>
>>>>> Sorry if this is considered noise to some, as I have a question which 
>>>>> is not specifically go related.
>>>>>
>>>>> I have a personal project in which I'd like to use go though.
>>>>>
>>>>> Basically, I'd like to create a complex search form, returning data 
>>>>> backed by an SQL database.
>>>>>
>>>>> To prevent SQL injection and for flexibility, I'm set on using an sql 
>>>>> builder library.
>>>>>
>>>>> However I'm not sure how to go about querying the data itself, via 
>>>>> query params, without creating lots of boiler plate and duplication.
>>>>>
>>>>> I'm wondering if a solution similar to what I'm looking for exists, as 
>>>>> I've never stumbled upon one...
>>>>>  
>>>>> I'm submitting my thoughts below, and would greatly appreciate 
>>>>> feedback :)
>>>>>
>>>>> ===NOTES_START===
>>>>> # Idea for query params, for a search form.
>>>>>
>>>>> Upon UI changes, javascript would generate the appropriate final query 
>>>>> string
>>>>>
>>>>> A query string could be typed in by a power user, to handle cases not 
>>>>> covered by a simpler UI (via the url or text input)
>>>>>
>>>>> ## First, create a solid CLI app. Then port it to the web via a JSON 
>>>>> API, that would simply consume the query string.
>>>>>
>>>>> ```
>>>>> go run ./cmd/query/main.go QUERY_STRING
>>>>> ```
>>>>>
>>>>> ## Query string format would follow this principle
>>>>>
>>>>>     PARAM_NAME : VALUE : OPERATOR
>>>>>
>>>>> ```
>>>>> # Commands
>>>>> columns:posted_on,short_descr:eq
>>>>> columns:posted_on,short_descr:hide
>>>>> columns:posting_id,posted_on,short_descr:show
>>>>>
>>>>> limit:10:eq
>>>>> limit:10  # would default to `eq`?
>>>>>
>>>>> page:1
>>>>> page:2
>>>>> offset:20
>>>>>
>>>>> # Filtering
>>>>> euros:11.94 # would default to `eq`?
>>>>> euros:11.94:eq
>>>>> euros:100:lt
>>>>> euros:100:lte
>>>>>
>>>>> comment:FIXME # would default to `eq`?
>>>>> comment:FIXME:eq
>>>>> comment:NULL:eq
>>>>> comment:NULL:ne
>>>>> comment:%tickets%:like
>>>>> comment:%Tickets%:ilike
>>>>>
>>>>> payee:Amazon|Google:re # regex
>>>>> payee:AMAZON|Google:rei # regex, case insensitive
>>>>>
>>>>> ```
>>>>>
>>>>> ## Question: how would I chain commands? I cannot use & in urls.
>>>>>
>>>>> ### Maybe with a pipe char
>>>>>
>>>>>     QUERY_STRING | QUERY_STRING | QUERY_STRING
>>>>>
>>>>> ### Or via AND, OR keywords
>>>>>
>>>>> ```
>>>>>     qs=QUERY_STRING
>>>>>
>>>>>     qs AND qs OR qs
>>>>> ```
>>>>>
>>>>> ### Boolean logic, force the use of parentheses?
>>>>>
>>>>> ```
>>>>>     qs=QUERY_STRING
>>>>>
>>>>>     (qs AND qs) OR (qs OR qs)
>>>>> ```
>>>>> ===NOTES_END===
>>>>>
>>>>> Basically, I guess I'm looking for some kind of DSL.
>>>>>
>>>>> I'm thinking of implementing a lexer/parser for this, but first I'd 
>>>>> like to make sure I'm not going to reinvent the wheel :)
>>>>>
>>>>> Thanks for your interest and input!
>>>>>
>>>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "golang-nuts" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/golang-nuts/Odr-LrUEAS8/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to 
>> golang-nuts...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> *Benjamin Thomas*
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to