This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: query type of an instance
- From: John Whittaker <john dot whittaker at sbcglobal dot net>
- To: Luis Casillas <luis at casillas dot org>
- Cc: kawa at sourceware dot org
- Date: Thu, 13 Dec 2007 19:13:03 -0800 (PST)
- Subject: Re: query type of an instance
Doh... I should have known about java.lang.Object,
although I'm newer to Java than Scheme.
Thanks for the macro examples. There is a treasure of
information there. I will have to digest these for a
while. It looks like you've been doing some database
programming with Kawa.
Thanks again,
John Whittaker
--- Luis Casillas <luis@casillas.org> wrote:
>
> 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
> ;;;
>
=== message truncated ===