summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
authorMarius Peter <dev@marius-peter.com>2025-11-17 17:47:17 +0100
committerMarius Peter <dev@marius-peter.com>2025-11-17 17:47:17 +0100
commitc0f93e8d41188fc4138a350430ee349b61ea0535 (patch)
tree5d88fd1195d65521c5e1a787cd773047605b7e72 /db
parent02ef60dd46676b5069aeae666b544b62f270ffd1 (diff)
raco fmt.
Diffstat (limited to 'db')
-rw-r--r--db/conn.rkt17
-rw-r--r--db/migrations.rkt268
-rw-r--r--db/seed.rkt73
3 files changed, 147 insertions, 211 deletions
diff --git a/db/conn.rkt b/db/conn.rkt
index e083d94..793cf03 100644
--- a/db/conn.rkt
+++ b/db/conn.rkt
@@ -12,11 +12,9 @@
(define (connect! #:path [path 'memory])
(cond
- [(connection? (current-conn))
- (printf "Database connection already exists: ~e\n" (current-conn))]
+ [(connection? (current-conn)) (printf "Database connection already exists: ~e\n" (current-conn))]
[else
- (current-conn (sqlite3-connect #:database path
- #:mode 'create))
+ (current-conn (sqlite3-connect #:database path #:mode 'create))
(printf "Created database connection at path: ~a\n" path)]))
(define (disconnect!)
@@ -25,10 +23,14 @@
(current-conn #f))
(define-syntax-rule (with-db body ...)
- (begin (connect!) body ...))
+ (begin
+ (connect!)
+ body ...))
(define-syntax-rule (with-tx body ...)
- (call-with-transaction (current-conn) (λ () body ...)))
+ (call-with-transaction (current-conn)
+ (λ ()
+ body ...)))
(module+ test
(require rackunit)
@@ -37,5 +39,4 @@
(check-true (connection? (current-conn)))
(disconnect!)
(check-equal? (current-conn) #f)
- (with-db
- (check-true (connection? (current-conn)))))
+ (with-db (check-true (connection? (current-conn)))))
diff --git a/db/migrations.rkt b/db/migrations.rkt
index fb8ab80..4007db4 100644
--- a/db/migrations.rkt
+++ b/db/migrations.rkt
@@ -14,203 +14,149 @@
(for ([pair (in-list (unbox migrations-box))])
(match pair
[(cons migration-name stmts)
- (with-tx
- (for ([stmt (in-list stmts)])
- (query-exec (current-conn) stmt)))
+ (with-tx (for ([stmt (in-list stmts)])
+ (query-exec (current-conn) stmt)))
(printf "Applied migration: ~a\n" migration-name)])))
(define-syntax-rule (define-migration migration-name sql)
- (let ((migrations (unbox migrations-box))
- (name-symbol (string->symbol migration-name)))
+ (let ([migrations (unbox migrations-box)]
+ [name-symbol (string->symbol migration-name)])
(if (assoc name-symbol migrations)
(error 'define-migration "migration '~a' declared more than once" migration-name)
(set-box! migrations-box (append migrations (list (cons name-symbol sql)))))))
-
;;;;;;;;
;; USERS
;;;;;;;;
(define-migration "create table users"
- (list
- (create-table #:if-not-exists
- users
- #:columns
- [id integer #:not-null]
- [name text #:not-null]
- [role_id integer]
- #:constraints
- (primary-key id)
- (unique name)
- (foreign-key role_id
- #:references (user_roles id)))))
+ (list (create-table #:if-not-exists users
+ #:columns [id integer #:not-null]
+ [name text #:not-null]
+ [role_id integer]
+ #:constraints (primary-key id)
+ (unique name)
+ (foreign-key role_id #:references (user_roles id)))))
(define-migration "create table user_roles"
- (list
- (create-table #:if-not-exists
- user_roles
- #:columns
- [id integer #:not-null]
- [name text #:not-null]
- #:constraints
- (primary-key id)
- (unique name))))
-
+ (list (create-table #:if-not-exists user_roles
+ #:columns [id integer #:not-null]
+ [name text #:not-null]
+ #:constraints (primary-key id)
+ (unique name))))
;;;;;;;;;;;;
;; NUTRIENTS
;;;;;;;;;;;;
(define-migration "create table nutrients"
- (list
- (create-table #:if-not-exists
- nutrients
- #:columns
- [id integer #:not-null]
- [canonical_name text #:not-null]
- [formula text #:not-null]
- #:constraints
- (primary-key id)
- (unique canonical_name)
- (unique formula))))
-
-(define-migration "create table nutrient_value_sets"
- (list
- (create-table #:if-not-exists
- nutrient_value_sets
- #:columns
- [id integer #:not-null]
- [nutrient_measurement_id integer]
- [nutrient_target_id integer]
- [crop_requirement_id integer]
- [fertilizer_product_id integer]
- #:constraints
- (primary-key id)
- (foreign-key nutrient_measurement_id
- #:references (nutrient_measurements id)
- #:on-delete #:cascade)
- (foreign-key nutrient_target_id
- #:references (nutrient_targets id)
- #:on-delete #:cascade)
- (foreign-key crop_requirement_id
- #:references (crop_requirements id)
- #:on-delete #:cascade)
- (foreign-key fertilizer_product_id
- #:references (fertilizer_products id)
- #:on-delete #:cascade)
- (unique nutrient_measurement_id)
- (unique nutrient_target_id)
- (unique crop_requirement_id)
- (unique fertilizer_product_id)
- (check (or (and (is-not-null nutrient_measurement_id)
- (is-null nutrient_target_id)
- (is-null crop_requirement_id)
- (is-null fertilizer_product_id))
- (and (is-null nutrient_measurement_id)
- (is-not-null nutrient_target_id)
- (is-null crop_requirement_id)
- (is-null fertilizer_product_id))
- (and (is-null nutrient_measurement_id)
- (is-null nutrient_target_id)
- (is-not-null crop_requirement_id)
- (is-null fertilizer_product_id))
- (and (is-null nutrient_measurement_id)
- (is-null nutrient_target_id)
- (is-null crop_requirement_id)
- (is-not-null fertilizer_product_id)))))
- "CREATE INDEX IF NOT EXISTS idx_nvs_meas ON nutrient_value_sets(nutrient_measurement_id)"
- "CREATE INDEX IF NOT EXISTS idx_nvs_targ ON nutrient_value_sets(nutrient_target_id)"
- "CREATE INDEX IF NOT EXISTS idx_nvs_crop ON nutrient_value_sets(crop_requirement_id)"
- "CREATE INDEX IF NOT EXISTS idx_nvs_prod ON nutrient_value_sets(fertilizer_product_id)"))
-
-(define-migration "create table nutrient_values"
- (list
- (create-table #:if-not-exists
- nutrient_values
- #:columns
- [value_set_id integer #:not-null]
- [nutrient_id integer #:not-null]
- [value_ppm real #:not-null]
- #:constraints
- (primary-key value_set_id nutrient_id)
- (foreign-key value_set_id
- #:references (nutrient_value_sets id)
- #:on-delete #:cascade)
- (foreign-key nutrient_id
- #:references (nutrients id)
- #:on-delete #:cascade))
- "CREATE INDEX IF NOT EXISTS idx_nv_set_nutrient ON nutrient_values(value_set_id, nutrient_id)"))
+ (list (create-table #:if-not-exists nutrients
+ #:columns [id integer #:not-null]
+ [canonical_name text #:not-null]
+ [formula text #:not-null]
+ #:constraints (primary-key id)
+ (unique canonical_name)
+ (unique formula))))
+
+(define-migration
+ "create table nutrient_value_sets"
+ (list
+ (create-table
+ #:if-not-exists nutrient_value_sets
+ #:columns [id integer #:not-null]
+ [nutrient_measurement_id integer]
+ [nutrient_target_id integer]
+ [crop_requirement_id integer]
+ [fertilizer_product_id integer]
+ #:constraints (primary-key id)
+ (foreign-key nutrient_measurement_id #:references (nutrient_measurements id) #:on-delete #:cascade)
+ (foreign-key nutrient_target_id #:references (nutrient_targets id) #:on-delete #:cascade)
+ (foreign-key crop_requirement_id #:references (crop_requirements id) #:on-delete #:cascade)
+ (foreign-key fertilizer_product_id #:references (fertilizer_products id) #:on-delete #:cascade)
+ (unique nutrient_measurement_id)
+ (unique nutrient_target_id)
+ (unique crop_requirement_id)
+ (unique fertilizer_product_id)
+ (check (or (and (is-not-null nutrient_measurement_id)
+ (is-null nutrient_target_id)
+ (is-null crop_requirement_id)
+ (is-null fertilizer_product_id))
+ (and (is-null nutrient_measurement_id)
+ (is-not-null nutrient_target_id)
+ (is-null crop_requirement_id)
+ (is-null fertilizer_product_id))
+ (and (is-null nutrient_measurement_id)
+ (is-null nutrient_target_id)
+ (is-not-null crop_requirement_id)
+ (is-null fertilizer_product_id))
+ (and (is-null nutrient_measurement_id)
+ (is-null nutrient_target_id)
+ (is-null crop_requirement_id)
+ (is-not-null fertilizer_product_id)))))
+ "CREATE INDEX IF NOT EXISTS idx_nvs_meas ON nutrient_value_sets(nutrient_measurement_id)"
+ "CREATE INDEX IF NOT EXISTS idx_nvs_targ ON nutrient_value_sets(nutrient_target_id)"
+ "CREATE INDEX IF NOT EXISTS idx_nvs_crop ON nutrient_value_sets(crop_requirement_id)"
+ "CREATE INDEX IF NOT EXISTS idx_nvs_prod ON nutrient_value_sets(fertilizer_product_id)"))
+
+(define-migration
+ "create table nutrient_values"
+ (list
+ (create-table #:if-not-exists nutrient_values
+ #:columns [value_set_id integer #:not-null]
+ [nutrient_id integer #:not-null]
+ [value_ppm real #:not-null]
+ #:constraints (primary-key value_set_id nutrient_id)
+ (foreign-key value_set_id #:references (nutrient_value_sets id) #:on-delete #:cascade)
+ (foreign-key nutrient_id #:references (nutrients id) #:on-delete #:cascade))
+ "CREATE INDEX IF NOT EXISTS idx_nv_set_nutrient ON nutrient_values(value_set_id, nutrient_id)"))
(define-migration "create table nutrient_measurements"
- (list
- (create-table #:if-not-exists
- nutrient_measurements
- #:columns
- [id integer #:not-null]
- ;; ISO8601 date
- [measured_on text #:not-null]
- #:constraints
- (primary-key id)
- (unique measured_on))))
+ (list (create-table #:if-not-exists nutrient_measurements
+ #:columns [id integer #:not-null]
+ ;; ISO8601 date
+ [measured_on text #:not-null]
+ #:constraints (primary-key id)
+ (unique measured_on))))
(define-migration "create table nutrient_targets"
- (list
- (create-table #:if-not-exists
- nutrient_targets
- #:columns
- [id integer #:not-null]
- ;; ISO8601 date
- [effective_on text #:not-null]
- #:constraints
- (primary-key id)
- (unique effective_on))))
-
+ (list (create-table #:if-not-exists nutrient_targets
+ #:columns [id integer #:not-null]
+ ;; ISO8601 date
+ [effective_on text #:not-null]
+ #:constraints (primary-key id)
+ (unique effective_on))))
;;;;;;;;
;; CROPS
;;;;;;;;
(define-migration "create table crops"
- (list
- (create-table #:if-not-exists
- crops
- #:columns
- [id integer #:not-null]
- [canonical_name integer #:not-null]
- #:constraints
- (primary-key id)
- (unique canonical_name))))
-
-(define-migration "create table crop_requirements"
- (list
- (create-table #:if-not-exists
- crop_requirements
- #:columns
- [id integer #:not-null]
- [crop_id integer]
- [profile text #:not-null]
- #:constraints
- (primary-key id)
- (foreign-key crop_id
- #:references (crops id)
- #:on-delete #:cascade))))
-
+ (list (create-table #:if-not-exists crops
+ #:columns [id integer #:not-null]
+ [canonical_name integer #:not-null]
+ #:constraints (primary-key id)
+ (unique canonical_name))))
+
+(define-migration
+ "create table crop_requirements"
+ (list (create-table #:if-not-exists crop_requirements
+ #:columns [id integer #:not-null]
+ [crop_id integer]
+ [profile text #:not-null]
+ #:constraints (primary-key id)
+ (foreign-key crop_id #:references (crops id) #:on-delete #:cascade))))
;;;;;;;;;;;;;;
;; FERTILIZERS
;;;;;;;;;;;;;;
(define-migration "create table fertilizer_products"
- (list
- (create-table #:if-not-exists
- fertilizer_products
- #:columns
- [id integer #:not-null]
- [canonical_name text #:not-null]
- [brand_name text]
- #:constraints
- (primary-key id)
- (unique canonical_name))))
+ (list (create-table #:if-not-exists fertilizer_products
+ #:columns [id integer #:not-null]
+ [canonical_name text #:not-null]
+ [brand_name text]
+ #:constraints (primary-key id)
+ (unique canonical_name))))
(module+ test
(connect!)
diff --git a/db/seed.rkt b/db/seed.rkt
index 4a765f6..881b9ef 100644
--- a/db/seed.rkt
+++ b/db/seed.rkt
@@ -20,29 +20,27 @@
(define (seed-nutrients!)
(define nutrient-names (map nutrient-name (get-nutrients)))
(define default-nutrients
- '(("Nitrate Nitrogen" "NNO3")
- ("Phosphorus" "P")
- ("Potassium" "K")
- ("Calcium" "Ca")
- ("Magnesium" "Mg")
- ("Sulfur" "S")
- ("Sodium" "Na")
- ("Chloride" "Cl")
- ("Silicon" "Si")
- ("Iron" "Fe")
- ("Zinc" "Zn")
- ("Boron" "B")
- ("Manganese" "Mn")
- ("Copper" "Cu")
- ("Molybdenum" "Mo")
- ("Ammonium Nitrogen" "NNH4")))
- (with-tx
- (for ([pair (in-list default-nutrients)])
- (define name (first pair))
- (define formula (second pair))
- ;; Ensure idempotence
- (unless (member name nutrient-names)
- (create-nutrient! name formula)))))
+ '(("Nitrate Nitrogen" "NNO3") ("Phosphorus" "P")
+ ("Potassium" "K")
+ ("Calcium" "Ca")
+ ("Magnesium" "Mg")
+ ("Sulfur" "S")
+ ("Sodium" "Na")
+ ("Chloride" "Cl")
+ ("Silicon" "Si")
+ ("Iron" "Fe")
+ ("Zinc" "Zn")
+ ("Boron" "B")
+ ("Manganese" "Mn")
+ ("Copper" "Cu")
+ ("Molybdenum" "Mo")
+ ("Ammonium Nitrogen" "NNH4")))
+ (with-tx (for ([pair (in-list default-nutrients)])
+ (define name (first pair))
+ (define formula (second pair))
+ ;; Ensure idempotence
+ (unless (member name nutrient-names)
+ (create-nutrient! name formula)))))
(define-runtime-path measurement-csv "data/dolibarr_nutrient_measurements_ppm.csv")
(define (seed-historical-nutrient-measurements!)
@@ -58,20 +56,15 @@
(define v (string->number (cdr nm)))
(cons n v)))
(create-nutrient-measurement! measured-on nutrient-values))
- (with-tx
- (csv-for-each row->seed! next-row)))
+ (with-tx (csv-for-each row->seed! next-row)))
(define (seed-crops!)
(define crop-names (map crop-name (get-crops)))
- (define default-crops '("salade"
- "laitue"
- "tomate"
- "framboise"))
- (with-tx
- (for ([name (in-list default-crops)])
- ;; Ensure idempotence
- (unless (member name crop-names)
- (create-crop! name)))))
+ (define default-crops '("salade" "laitue" "tomate" "framboise"))
+ (with-tx (for ([name (in-list default-crops)])
+ ;; Ensure idempotence
+ (unless (member name crop-names)
+ (create-crop! name)))))
(define-runtime-path requirements-csv "data/dolibarr_crop_requirements_ppm.csv")
(define (seed-crop-requirements!)
@@ -91,10 +84,8 @@
[(non-empty-string? crop-name)
(define crop (get-crop #:name crop-name))
(create-crop-requirement! profile nutrient-values crop)]
- [else
- (create-crop-requirement! profile nutrient-values)]))
- (with-tx
- (csv-for-each row->seed! next-row)))
+ [else (create-crop-requirement! profile nutrient-values)]))
+ (with-tx (csv-for-each row->seed! next-row)))
(define-runtime-path fertilizer-csv "data/dolibarr_fertilizer_compositions_percentage.csv")
(define (seed-existing-fertilizer-products!)
@@ -113,10 +104,8 @@
(cond
[(non-empty-string? brand-name)
(create-fertilizer-product! canonical-name nutrient-values brand-name)]
- [else
- (create-fertilizer-product! canonical-name nutrient-values)]))
- (with-tx
- (csv-for-each row->seed! next-row)))
+ [else (create-fertilizer-product! canonical-name nutrient-values)]))
+ (with-tx (csv-for-each row->seed! next-row)))
(define seed-sequence
(list (cons "nutrients" seed-nutrients!)
Copyright 2019--2026 Marius PETER