43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
+
+
|
(contract-out
;; Utility functions
[log-query (string? . -> . void?)]
[vector->hash (vector? (listof symbolish?) . -> . hash?)]
[backtick (stringish? . -> . string?)]
[list->sql-fields ((listof stringish?) . -> . string?)]
[list->sql-parameters ((listof any/c) . -> . string?)]
[bool->int (any/c . -> . exact-integer?)]
[int->bool (exact-integer? . -> . boolean?)]
;; Simple SQL makers
[make-table-schema ((string? (listof stringish?))
(#:primary-key-cols (listof stringish?))
. ->* . string?)]
[make-insert/replace-query (stringish? (listof stringish?) . -> . string?)]
[make-select-query (stringish? (listof stringish?) #:where string? . -> . string?)]
|
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
|
;; ~~~ Provided utility functions ~~~
(define (backtick str) (format "`~a`" str))
(define (list->sql-fields fields) (apply string-append (add-between (map backtick fields) ", ")))
(define (list->sql-parameters fields)
(apply string-append (add-between (map (λ(x) (format "?~a" (add1 x))) (range (length fields))) ", ")))
;; For storing/reading boolean values (SQLite uses integers)
(define (bool->int b?)
(cond [b? 1] [else 0]))
(define (int->bool i)
(not (= i 0)))
;; TESTING: utility functions…
(module+ test
(check-equal? (backtick "field") "`field`")
(check-equal? (list->sql-fields '("f1" "f2" "f3")) "`f1`, `f2`, `f3`")
(check-equal? (list->sql-fields '(f1 f2 f3)) "`f1`, `f2`, `f3`") ; Can use symbols too
(check-equal? (list->sql-parameters '("name" "rank" "serial")) "?1, ?2, ?3")
(check-equal? (list->sql-parameters '(name rank serial)) "?1, ?2, ?3")
(check-equal? (weave '(x y z) '(1 2 3)) '(x 1 y 2 z 3)))
(check-equal? (weave '(x y z) '(1 2 3)) '(x 1 y 2 z 3))
(check-equal? (bool->int #f) 0)
(check-equal? (bool->int #t) 1)
(check-equal? (bool->int "xblargh") 1)
(check-equal? (int->bool 0) #f)
(check-equal? (int->bool 1) #t)
(check-equal? (int->bool -1) #t)
(check-equal? (int->bool 37) #t)
(check-exn exn:fail? (lambda () (int->bool "x"))))
;; ~~~ Public functions ~~~
;; Prints to stdout if logging is on
(define (log-query q) (unless (not (sqltools:log-queries?)) (println q)))
;; Using a list of field names, convert a vector into a hash that uses the
|