in-query
returns a sequence of single value (#468)
this is an trade-off since dynamically-valued interfaces are almost impossible to typecheck https://github.com/racket/typed-racket/pull/468 Also, the `SQL-Datum` is now more precision, since `Any` shadows all opaque types (such as `SQL-Null`) which may lead to contract errors.
This commit is contained in:
parent
4e02bd44ab
commit
3077af848b
|
@ -1,24 +1,26 @@
|
|||
#lang typed/racket
|
||||
#lang typed/racket/base
|
||||
|
||||
(provide (all-defined-out))
|
||||
|
||||
(require (for-syntax racket/base))
|
||||
(require (for-syntax racket/syntax))
|
||||
|
||||
(define-type Data-Source data-source)
|
||||
(define-type Simple-Result simple-result)
|
||||
(define-type Rows-Result rows-result)
|
||||
|
||||
(define-type Null-Mode (U 'preserve-null 'list))
|
||||
(define-type Group-Mode (U 'preserve-null 'list))
|
||||
(define-type Isolation-Level (U 'serializable 'repeatable-read 'read-committed 'read-uncommitted False))
|
||||
(define-type Schema-Option (U 'search-or-current 'search 'current))
|
||||
|
||||
(define-type SQL-Datum Any)
|
||||
(define-type SQL-Datum (U Boolean String Real Char Bytes SQL-Null))
|
||||
(define-type SQL-Type (List Boolean (Option Symbol) SQL-Datum))
|
||||
(define-type Statement (U String Prepared-Statement Virtual-Statement Statement-Binding))
|
||||
|
||||
(define-type SQL-Field (U String Natural))
|
||||
(define-type SQL-Grouping (U SQL-Field (Vectorof SQL-Field)))
|
||||
(define-type SQL-Group (U SQL-Grouping (Vectorof SQL-Grouping)))
|
||||
(define-type SQL-Group (U SQL-Grouping (Listof SQL-Grouping)))
|
||||
(define-type SQL-Dictionary (HashTable SQL-Field (U (Vectorof SQL-Datum) (Listof (Vectorof SQL-Datum)))))
|
||||
|
||||
(require/typed/provide
|
||||
db/base
|
||||
|
@ -59,22 +61,22 @@
|
|||
(require/typed/provide
|
||||
db/base
|
||||
[query-exec (-> Connection Statement SQL-Datum * Void)]
|
||||
[query-list (All (a) (-> Connection Statement SQL-Datum * (Listof a)))]
|
||||
[query-list (-> Connection Statement SQL-Datum * (Listof SQL-Datum))]
|
||||
[query-row (-> Connection Statement SQL-Datum * (Vectorof SQL-Datum))]
|
||||
[query-maybe-row (-> Connection Statement SQL-Datum * (Option (Vectorof SQL-Datum)))]
|
||||
[query-value (-> Connection Statement SQL-Datum * SQL-Datum)]
|
||||
[query-maybe-value (-> Connection Statement SQL-Datum * (Option SQL-Datum))]
|
||||
[query-rows (-> Connection Statement
|
||||
[#:group SQL-Group]
|
||||
[#:group-mode (Listof Null-Mode)]
|
||||
[#:group-mode (Listof Group-Mode)]
|
||||
SQL-Datum *
|
||||
(Listof (Vectorof SQL-Datum)))]
|
||||
[in-query (-> Connection Statement
|
||||
[#:fetch (U Positive-Integer +inf.0)]
|
||||
[#:group SQL-Group]
|
||||
[#:group-mode (Listof Null-Mode)]
|
||||
[#:group-mode (Listof Group-Mode)]
|
||||
SQL-Datum *
|
||||
(Sequenceof (Vectorof SQL-Datum)))])
|
||||
(Sequenceof SQL-Datum))])
|
||||
|
||||
(require/typed/provide
|
||||
db/base
|
||||
|
@ -82,13 +84,13 @@
|
|||
[#:struct rows-result ([headers : (Listof Any)] [rows : (Listof (Vectorof SQL-Datum))])]
|
||||
[query (-> Connection Statement SQL-Datum * (U Simple-Result Rows-Result))]
|
||||
[group-rows (->* (Rows-Result #:group SQL-Group)
|
||||
(#:group-mode (Listof Null-Mode))
|
||||
(#:group-mode (Listof Group-Mode))
|
||||
Rows-Result)]
|
||||
[rows->dict (->* (Rows-Result
|
||||
#:key SQL-Field ; if Grouping/c: required a flat contract but got a chaperone one
|
||||
#:key SQL-Field
|
||||
#:value SQL-Grouping)
|
||||
(#:value-mode (Listof Null-Mode))
|
||||
(HashTable (U SQL-Field SQL-Null) SQL-Grouping))])
|
||||
(#:value-mode (Listof Group-Mode))
|
||||
SQL-Dictionary)])
|
||||
|
||||
(require/typed/provide
|
||||
db/base
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#lang typed/racket
|
||||
#lang typed/racket/base
|
||||
|
||||
(provide (all-defined-out))
|
||||
|
||||
|
|
32
typed-racket-test/succeed/pr468-in-query.rkt
Normal file
32
typed-racket-test/succeed/pr468-in-query.rkt
Normal file
|
@ -0,0 +1,32 @@
|
|||
#lang typed/racket
|
||||
|
||||
;; https://github.com/racket/typed-racket/issues/460
|
||||
;; https://github.com/racket/typed-racket/pull/468
|
||||
|
||||
(require typed/db)
|
||||
|
||||
(define sqlite : Connection (sqlite3-connect #:database 'memory))
|
||||
|
||||
(struct master ([id : Integer] [type : Symbol] [name : String] [sql : String])
|
||||
#:prefab #:type-name Master
|
||||
#:constructor-name make-master)
|
||||
|
||||
(define record : Master
|
||||
(make-master (current-milliseconds) 'table "manual_index"
|
||||
"CREATE TABLE manual_index(id, name, content);"))
|
||||
|
||||
(query-exec sqlite (master-sql record))
|
||||
(query-exec sqlite "insert into manual_index values ($1, $2, $3)"
|
||||
(master-id record) (master-name record) (~s record))
|
||||
|
||||
(for ([s (in-query sqlite "SELECT content FROM manual_index WHERE name = $1;" (master-name record))])
|
||||
(define ?record (with-input-from-string (~a s) read))
|
||||
(if (not (master? ?record))
|
||||
(fprintf (current-error-port) "in-query: unexpected value: ~s"
|
||||
?record)
|
||||
(fprintf (current-output-port) "[~a]~a: ~s~n"
|
||||
(master-type ?record)
|
||||
(master-name ?record)
|
||||
(master-sql ?record))))
|
||||
|
||||
(disconnect sqlite)
|
Loading…
Reference in New Issue
Block a user