diff --git a/typed-racket-more/typed/db/base.rkt b/typed-racket-more/typed/db/base.rkt index f8be5e47..ad1edf2a 100644 --- a/typed-racket-more/typed/db/base.rkt +++ b/typed-racket-more/typed/db/base.rkt @@ -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 diff --git a/typed-racket-more/typed/db/sqlite3.rkt b/typed-racket-more/typed/db/sqlite3.rkt index 38fec8a0..b0e5acfa 100644 --- a/typed-racket-more/typed/db/sqlite3.rkt +++ b/typed-racket-more/typed/db/sqlite3.rkt @@ -1,4 +1,4 @@ -#lang typed/racket +#lang typed/racket/base (provide (all-defined-out)) diff --git a/typed-racket-test/succeed/pr468-in-query.rkt b/typed-racket-test/succeed/pr468-in-query.rkt new file mode 100644 index 00000000..502f7cbf --- /dev/null +++ b/typed-racket-test/succeed/pr468-in-query.rkt @@ -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)