On 1/31/2019 10:58 AM, hashim muqtadir wrote:

The test in my following code raises an error saying that when I call select/f, the result doesn't satisfy `sql-statement?`.

I've no idea why, the only vague idea I have is that it may have something to do with the fact that it was essentially eval'd in a separate namespace.

Any ideas?

    #lang racket

    (require db)

    (define sql-namespace (make-base-empty-namespace))
    (parameterize ([current-namespace sql-namespace])
      (namespace-require 'sql sql-namespace))

    (struct Select-spec
      (tbl  ;; symbol
       col-exprs  ;; listof symbols
       limit  ;; number
       order-by)) ;; listof select symbols

    (define (select/f sel-spec)
      (eval
       `(select ,@(Select-spec-col-exprs sel-spec)
                #:from ,(Select-spec-tbl sel-spec)
                ,@(let ([lim (Select-spec-limit sel-spec)]
                        [order (Select-spec-order-by sel-spec)])
                    (if lim
                        `(#:limit ,lim #:order-by ,@order)
                        '())))
       sql-namespace))

    (module+ test
      (require sql)
      (require rackunit)
      (check-equal?
       (sql-statement->string
        (select/f
          (Select-spec
           'd
           '(a b c)
           10
           '(a b))))
       (sql-statement->string
        (select a b c
                #:from d #:order-by a b #:limit 10))))

    (provide select/f
             Select-spec)


My main reason for doing this was that the statement-producing macros provided by the sql package were, well, macros, so I couldn't pass in a list of columns and get a statement. What I want to do is have a struct like the one I made in this snippet, and use functions to include/exclude columns, before finally passing it off to a function that produces the statement.

I agree with John that you probably should not be using eval here. Eval almost always is the wrong answer.

But as to why your code is not working: there is a problem with structs and namespaces - I don't recall the technical specifics, but the gist is that simply copying a struct into a different namespace doesn't work - it results in a new, auto-created struct type - which isn't what you want.  If order to use a struct across namespaces, the module that defines the struct must be required into each namespace that uses the struct.

George

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

Reply via email to