This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: query type of an instance
- From: Luis Casillas <luis at casillas dot org>
- To: John Whittaker <john dot whittaker at sbcglobal dot net>
- Cc: kawa at sourceware dot org
- Date: Thu, 13 Dec 2007 18:18:46 -0800
- Subject: Re: query type of an instance
- References: <965502.78654.qm@web81102.mail.mud.yahoo.com>
On Dec 13, 2007, at 3:23 PM, John Whittaker wrote:
Now my newest newbie question... I hope I am not
missing something obvious. How do you query the type
of an object? I know about instance?, but if I knew
enough about an object's type to use instance? I would
have half my answer :). For example, if I have an
instance of sun.jdbc.odbc.JdbcOdbcResultSet, what
function can I call with that instance which returns
the class sun.jdbc.odbc.JdbcOdbcResultSet?
You can just call the class() method on objects. Somewhere near the
top of your source file:
(define-namespace Object <java.lang.Object>)
... and then, when you want the class of foo:
(Object:class foo)
Finally, what all this is really leading up to is a
bigger Kawa and Scheme macro question. I'd like to
have a macro (maybe a function would do as well)which
I will call "with-result-set" (perhaps
"collect-result-set" would be better). You would give
it a result set instance (say a
sun.jdbc.odbc.JdbcOdbcResult) and a variable number of
pairs consisting of a type and a field name. So an
invocation might look like (with-result-set my-rs
'(String "Field1") '(Float "Field2") ...). It would
return a list of lists of all those fields in the
result set: (("abc" 42) ("def" 56.2) ...).
I'm really green on syntax-case etc. I think it
should be possible to do this, and perhaps using a
macro if the types are known at compile time. Any
thoughts?
I have a set of macros that may get you started, though they're not
exactly what you want. You can probably write collect-result-set
fairly easily as a function using some of these macros. How to use
them is left as an exercise on how to read Scheme macro definitions :-).
A warning, however: I've modified this slightly to remove
dependencies on other code I'm not providing, and I haven't tested
the modifications. Don't be surprised if some very small
modifications are needed.
(define-namespace Connection <java.sql.Connection>)
(define-namespace Statement <java.sql.Statement>)
(define-namespace ResultSet <java.sql.ResultSet>)
;;;
;;; with-jdbc-result-set
;;;
(define-syntax (with-jdbc-result-set stx)
(syntax-case stx ()
((_ (var result-set-expr)
expr . exprs)
(syntax
(let ((var result-set-expr))
(try-finally
(begin expr . exprs)
(unless (eq? #!null var)
(ResultSet:close var))))))))
;;;
;;; with-jdbc-connection
;;;
(define-syntax (with-jdbc-connection stx)
(syntax-case stx ()
((with-jdbc-connection (var jdbc-connection-expr)
expr . exprs)
(syntax
(let ((var jdbc-connection-expr))
(try-finally
(begin expr . exprs)
(unless (eq? #!null var)
(Connection:close var))))))))
;;;
;;; with-jdbc-statement
;;;
(define-syntax (with-jdbc-statement stx)
(syntax-case stx ()
((_ (var jdbc-statement-expr)
expr . exprs)
(syntax
(let ((var jdbc-statement-expr))
(try-finally
(begin expr . exprs)
(unless (eq? #!null var)
(Statement:close var))))))))
;;;
;;; do-query-results
;;;
(define-syntax (do-query-results stx)
(syntax-case stx (exit-if:)
((_ (var connection-expr query-str-expr)
exit-if: exit-cond
expr . exprs)
(syntax
(let ((conn connection-expr)
(query-str query-str-expr))
(with-jdbc-statement (stmt (Connection:create-statement conn))
(with-jdbc-result-set (var (Statement:executeQuery stmt
query-str))
(let loop ()
(when (ResultSet:next var)
(unless exit-cond
(begin expr . exprs)
(loop)))))))))
((_ (var connection-expr query-str)
expr . exprs)
(syntax
(do-query-results (var connection-expr query-str)
exit-if: #f
expr . exprs)))))
Is there a function analogous to macro-expand in Kawa?
I sometimes use the following macros to debug macro expansion. The
output isn't nearly as friendly as I'd like, but it's better than
nothing.
;;;
;;; syntax-case-debug
;;;
;;; Drop-in replacement for syntax-case. Prints each macro expansion
;;; at compile-time with relatively "friendly" output, using
;;; syntax-object->datum on the input and expanded syntax forms.
;;; Caveat: because of hygiene, two distinct identifiers can have the
;;; same datum, and print the same.
;;;
(define-syntax syntax-case-debug
(syntax-rules ()
((_ stx (literal ...) clause ...)
(let ((result (syntax-case stx (literal ...) clause ...)))
(format #t "syntax-case-trace: ~S~%=> ~S~%~%"
(syntax-object->datum stx)
(syntax-object->datum result))
result))))
;;;
;;; syntax-case-trace
;;;
;;; Like syntax-case-debug, but prints the syntax object and not its
;;; datum. Output is more "unfriendly" this way, but this can
;;; distinguish between two different identifiers with the same datum.
;;;
(define-syntax syntax-case-trace
(syntax-rules ()
((_ stx (literal ...) clause ...)
(let ((result (syntax-case stx (literal ...) clause ...)))
(format #t "syntax-case-trace: ~S~%=> ~S~%~%"
stx result)
result))))
;;;
;;; syntax-rules-debug
;;;
;;; Like syntax-case-debug, but for syntax-rules.
;;;
(define-syntax syntax-rules-debug
(lambda (x)
(syntax-case x ()
((_ (i ...) ((keyword . pattern) template) ...)
(syntax
(lambda (x)
(syntax-case-debug x (i ...)
((dummy . pattern) (syntax template))
...)))))))
;;;
;;; syntax-rules-trace
;;;
;;; Like syntax-case-trace, but for syntax-rules.
;;;
(define-syntax syntax-rules-trace
(lambda (x)
(syntax-case x ()
((_ (i ...) ((keyword . pattern) template) ...)
(syntax
(lambda (x)
(syntax-case-trace x (i ...)
((dummy . pattern) (syntax template))
...)))))))