``` @SqlMarker object SQLBuilder { fun query(i...
# announcements
m
Copy code
@SqlMarker
object SQLBuilder {
    fun query(init: SqlSelectBuilder.() -> Unit): SqlSelectBuilder {
        val builder = SqlSelectBuilder()
        builder.init()
        return builder
    }
}
I have this, but somehow the compiler still let me do this eventough I marked it with DSLMarker
Copy code
val query = SQLBuilder.query {
        
        query { 
            
        }
what am I doing wrong? 😞
k
Can you share a full (compilable) code sample?
m
there is module called
sqlbuilder
k
Yikes that code just screams "SQL injection"
m
yes, it should only demonstrate kotlin DSL, it wont be some serious production code anyway
k
I'd still recommend you to find a better example 🙁
That code works fine for me, are you sure you didn't accidentally statically import the query function?
(I mean the compiler rejects that code)
Do you have something like this at the top of your test file?
import com.minki.sqlbuilder.SQLBuilder.query
m
yes, in my main file
k
Then that's the problem simple smile
m
I see, but I can still do something like this
Copy code
select {
            select { 
                
            }
eventough I have this
Copy code
@SqlMarker
class SqlSelectBuilder
k
That's because your forgot
@SqlMarker
on the
Select
class.
m
another question out of curiosity: if I mark Condition with
@SqlMarker
, I still can do this:
Copy code
or {
     or { }
}
why?
k
Because the first
or
brings an explicit new
Condition
into scope, which you then call the second or on.
m
brings an explicit new
what do you mean exactly by that? because I construct a new object?
k
So the purpose of
@DslMarker
is to prevent receivers from the upper scopes being accidentally visible in the more nested scopes.
Copy code
where { //1
    or { //2
        or { //3
1 calls its lambda with a
Condition
scope, and on that scope you call
or
2. Then 2 calls its lambda with a new
Condition
receiver, and on that new receiver you can still call
or
. 2's lambda shouldn't be able to access 1's
Condition
, and indeed it can't, it uses 2's
Condition
instead.
Note that it's not about creating a new object, you could just keep passing the same
Condition
object in the
or
code and it'd still work the same. This is a compile-time thing, not a runtime thing.
m
I get it, very good explained, thank you and kudos
k
You're welcome!
(I still think they should take down that blog post or at least put a big disclaimer on it)
m
I added a comment in my code to not take sql string literal generation as decent practice
👍 1