This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: query type of an instance



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))
            ...)))))))


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]