add last inserted row, # changes to simple-result info
The info keys are 'insert-id, 'affected-rows, as for mysql.
This commit is contained in:
parent
a6f03ee38f
commit
681558328e
|
@ -362,7 +362,7 @@
|
|||
[(struct ok-packet (affected-rows insert-id status warnings message))
|
||||
(when wbox (set-box! wbox warnings))
|
||||
(vector 'command `((affected-rows . ,affected-rows)
|
||||
(insert-id . ,insert-id)
|
||||
(insert-id . ,(if (zero? insert-id) #f insert-id))
|
||||
(status . ,status)
|
||||
(message . ,message)))]
|
||||
[(struct result-set-header-packet (fields extra))
|
||||
|
|
|
@ -379,7 +379,7 @@
|
|||
|
||||
(define/private (query1:expect-completion fsym)
|
||||
(match (recv-message fsym)
|
||||
[(struct CommandComplete (command)) `((command . ,command))]
|
||||
[(struct CommandComplete (command)) command]
|
||||
[(struct EmptyQueryResponse ()) '()]
|
||||
[other-r (query1:error fsym other-r)]))
|
||||
|
||||
|
|
|
@ -267,7 +267,7 @@
|
|||
(define (parse:CommandComplete p)
|
||||
(with-length-in p #\C
|
||||
(let* ([command (io:read-null-terminated-string p)])
|
||||
(make-CommandComplete command))))
|
||||
(make-CommandComplete (string->command-alist command)))))
|
||||
|
||||
(define-struct CopyInResponse (format column-formats) #:transparent)
|
||||
(define (parse:CopyInResponse p)
|
||||
|
@ -527,45 +527,25 @@
|
|||
[(transaction) #\T]
|
||||
[(failed) #\E]))
|
||||
|
||||
(define (string->command s)
|
||||
(cond [(regexp-match #rx"^SELECT *$" s)
|
||||
=> (lambda (m) (list 'select))]
|
||||
[(regexp-match #rx"^INSERT ([0-9]*) ([0-9]*) *$" s)
|
||||
(define (string->command-alist s)
|
||||
(cond [(regexp-match #rx"^INSERT ([0-9]*) ([0-9]*) *$" s)
|
||||
=> (lambda (m)
|
||||
(list 'insert
|
||||
(string->number (cadr m))
|
||||
(string->number (caddr m))))]
|
||||
[(regexp-match #rx"^DELETE ([0-9]* *$)" s)
|
||||
`((insert-id . ,(let ([oid (string->number (cadr m))])
|
||||
(if (zero? oid) #f oid)))
|
||||
(affected-rows . ,(string->number (caddr m)))))]
|
||||
[(regexp-match #rx"^DELETE ([0-9]*) *$" s)
|
||||
=> (lambda (m)
|
||||
(list 'delete (string->number (cadr m))))]
|
||||
`((affected-rows . ,(string->number (cadr m)))))]
|
||||
[(regexp-match #rx"^UPDATE ([0-9]*) *$" s)
|
||||
=> (lambda (m)
|
||||
(list 'update (string->number (cadr m))))]
|
||||
[(regexp-match #rx"^MOVE ([0-9]*) *$" s)
|
||||
=> (lambda (m)
|
||||
(list 'move (string->number (cadr m))))]
|
||||
[(regexp-match #rx"^FETCH ([0-9]*) *$" s)
|
||||
=> (lambda (m)
|
||||
(list 'fetch (string->number (cadr m))))]
|
||||
[(regexp-match #rx"^(CREATE|ALTER|DROP) ([A-Z]*) *$" s)
|
||||
=> (lambda (m)
|
||||
(list (string->symbol (string-downcase (cadr m)))
|
||||
(string->symbol (string-downcase (caddr m)))))]
|
||||
[else s]))
|
||||
|
||||
(define (command->string s)
|
||||
(if (list? s)
|
||||
(apply string-append
|
||||
(case (car s)
|
||||
[(insert) "INSERT"]
|
||||
[(delete) "DELETE"]
|
||||
[(update) "UPDATE"]
|
||||
[(move) "MOVE"]
|
||||
[(fetch) "FETCH"]
|
||||
[else s])
|
||||
(map (lambda (n) (format " ~a" n))
|
||||
(cdr s)))
|
||||
s))
|
||||
`((affected-rows . ,(string->number (cadr m)))))]
|
||||
#|
|
||||
[(regexp-match #rx"^SELECT *$" s) ...]
|
||||
[(regexp-match #rx"^MOVE ([0-9]*) *$" s) ...]
|
||||
[(regexp-match #rx"^FETCH ([0-9]*) *$" s) ...]
|
||||
[(regexp-match #rx"^(CREATE|ALTER|DROP) ([A-Z]*) *$" s) ...]
|
||||
|#
|
||||
[else '()]))
|
||||
|
||||
|
||||
;; dvec layout is #(name table-oid col-oid typeid typelen typemod text/binary)
|
||||
|
|
|
@ -67,13 +67,17 @@
|
|||
(for ([i (in-naturals 1)]
|
||||
[param (in-list params)])
|
||||
(load-param fsym db stmt i param))
|
||||
(let ([info
|
||||
(for/list ([i (in-range (sqlite3_column_count stmt))])
|
||||
`((name . ,(sqlite3_column_name stmt i))
|
||||
(decltype . ,(sqlite3_column_decltype stmt i))))]
|
||||
[result
|
||||
(or cursor?
|
||||
(step* fsym db stmt #f +inf.0))])
|
||||
(let* ([info
|
||||
(for/list ([i (in-range (sqlite3_column_count stmt))])
|
||||
`((name . ,(sqlite3_column_name stmt i))
|
||||
(decltype . ,(sqlite3_column_decltype stmt i))))]
|
||||
[saved-last-insert-rowid
|
||||
(and (null? info) (sqlite3_last_insert_rowid db))]
|
||||
[saved-total-changes
|
||||
(and (null? info) (sqlite3_total_changes db))]
|
||||
[result
|
||||
(or cursor?
|
||||
(step* fsym db stmt #f +inf.0))])
|
||||
(unless (eq? (get-tx-status) 'invalid)
|
||||
(set-tx-status! fsym (read-tx-status)))
|
||||
(unless cursor?
|
||||
|
@ -83,7 +87,18 @@
|
|||
[(and (pair? info) cursor?)
|
||||
(cursor-result info pst (box #f))]
|
||||
[else
|
||||
(simple-result '())])))))
|
||||
(simple-result
|
||||
(let ([last-insert-rowid (sqlite3_last_insert_rowid db)]
|
||||
[total-changes (sqlite3_total_changes db)])
|
||||
;; Not all statements clear last_insert_rowid, changes; so
|
||||
;; extra guards to make sure results are relevant.
|
||||
`((insert-id
|
||||
. ,(and (not (= last-insert-rowid saved-last-insert-rowid))
|
||||
last-insert-rowid))
|
||||
(affected-rows
|
||||
. ,(if (> total-changes saved-total-changes)
|
||||
(sqlite3_changes db)
|
||||
0)))))])))))
|
||||
|
||||
(define/public (fetch/cursor fsym cursor fetch-size)
|
||||
(let ([pst (cursor-result-pst cursor)]
|
||||
|
|
|
@ -182,10 +182,14 @@
|
|||
(_fun _sqlite3_database
|
||||
-> _int))
|
||||
|
||||
(define-sqlite sqlite3_last_insert_rowid
|
||||
(define-sqlite sqlite3_total_changes
|
||||
(_fun _sqlite3_database
|
||||
-> _int))
|
||||
|
||||
(define-sqlite sqlite3_last_insert_rowid
|
||||
(_fun _sqlite3_database
|
||||
-> _int64))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
#|
|
||||
|
|
|
@ -297,14 +297,39 @@ A general query result is either a @racket[simple-result] or a
|
|||
@racket[rows-result].
|
||||
|
||||
@defstruct*[simple-result
|
||||
([info any/c])]{
|
||||
([info (listof (cons/c symbol? any/c))])]{
|
||||
|
||||
Represents the result of a SQL statement that does not return a
|
||||
relation, such as an @tt{INSERT} or @tt{DELETE} statement.
|
||||
|
||||
The @racket[info] field is usually an association list, but do not
|
||||
rely on its contents; it varies based on database system and may
|
||||
change in future versions of this library (even new minor versions).
|
||||
The @racket[info] field is an association list, but its contents vary
|
||||
based on database system and may change in future versions of this
|
||||
library (even new minor versions). The following keys are supported for
|
||||
multiple database systems:
|
||||
|
||||
@itemlist[
|
||||
|
||||
@item{@racket['insert-id]: If the value is a positive integer, the
|
||||
statement was an @tt{INSERT} statement and the value is a
|
||||
system-specific identifier for the inserted row. For PostgreSQL, the
|
||||
value is the row's OID, if the table has OIDs (for an alternative, see
|
||||
the @tt{INSERT ... RETURNING} statement). For MySQL, the value is the
|
||||
same as the result of
|
||||
@hyperlink["http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id"]{last_insert_id}
|
||||
function---that is, the value of the row's @tt{AUTO_INCREMENT}
|
||||
field. If there is no such field, the value is @racket[#f]. For
|
||||
SQLite, the value is the same as the result of the
|
||||
@hyperlink["http://www.sqlite.org/lang_corefunc.html#last_insert_rowid"]{last_insert_rowid}
|
||||
function---that is, the
|
||||
@hyperlink["http://www.sqlite.org/lang_createtable.html#rowid"]{ROWID}
|
||||
of the inserted row.}
|
||||
|
||||
@item{@racket['affected-rows]: The number (a nonnegative integer) of
|
||||
rows inserted by an @tt{INSERT} statement, modified by an @tt{UPDATE}
|
||||
statement, or deleted by a @tt{DELETE} statement. Only directly
|
||||
affected rows are counted; rows affected because of triggers or
|
||||
integrity constraint actions are not counted.}
|
||||
]
|
||||
}
|
||||
|
||||
@defstruct*[rows-result
|
||||
|
|
Loading…
Reference in New Issue
Block a user