Reputation: 33833
https://docs.racket-lang.org/sql/ is a nice DSL for preparing SQL statements, which works with the db
library.
The docs show an example like:
(require sql)
(create-table #:temporary the_numbers
#:columns [n integer #:not-null] [d varchar])
In this code the_numbers
is not an identifier, it's treated literally as the name of the table.
What I want to do is something like:
(require sql)
(define (my-create-table table-name)
(create-table #:temporary table-name
#:columns [n integer #:not-null] [d varchar]))
This gives an error because it treats table-name
as the actual table name and it doesn't like the hyphen in it (I think it should be possible to use that as a table name but I guess I need to do something more to have the lib quote it properly...)
I am new to Racket and don't know many tricks. I tried using 'table-name
but that doesn't work.
Upvotes: 4
Views: 132
Reputation: 10653
The features you need are described in the Dynamic Statement Composition and SQL Injection of the docs. You can write the Ident for the table's name as (Ident:AST ,expr)
, where expr
produces an Ident AST value.
> (define (my-create-table table-name)
(create-table #:temporary (Ident:AST ,(make-ident-ast table-name))
#:columns [n integer #:not-null] [d varchar]))
> (my-create-table 'the_numbers)
(sql-statement
"CREATE TEMPORARY TABLE the_numbers (n integer NOT NULL, d varchar)")
Upvotes: 3
Reputation: 1969
Here's something that should work for you:
#lang racket
(require syntax/parse/define)
(require sql)
(define-simple-macro (my-create-table table-name:id)
(create-table #:temporary table-name
#:columns [n integer #:not-null] [d varchar]))
(my-create-table my_table_name)
This creates a macro called my-create-table
. What that essentially does is it syntactically replaces (hygienically) the expression (my-create-table <some-id>)
, where <some-id>
is any identifier, with the expression below (the create-table
expression), replacing table-name
with the id given in the original syntax.
Macros are cool.
Upvotes: 1