summaryrefslogtreecommitdiff
path: root/db/seed.rkt
blob: 753065133c330624379a235c1660e4485dccc934 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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
#lang racket

(provide seed-database!)

(require csv-reading
         racket/runtime-path
         "conn.rkt"
         "../models/nutrient.rkt"
         "../models/nutrient-measurement.rkt"
         "../models/crop.rkt"
         "../models/crop-requirement.rkt"
         "../models/fertilizer-product.rkt")

(define (seed-database!)
  (for ([seed-function (in-list (seed-sequence))])
    (seed-function)))

(define (seed-sequence)
  (list seed-nutrients!
        seed-historical-nutrient-measurements!
        seed-crops!
        seed-crop-requirements!
        seed-existing-fertilizer-products!))

(define (seed-nutrients!)
  (define nutrient-names (map nutrient-canonical-name (get-nutrients)))
  (define default-nutrients
    '(("Nitrate Nitrogen" "Azote nitrique" "NNO3") ("Phosphorus" "Phosphore" "P")
                                                   ("Potassium" "Potassium" "K")
                                                   ("Calcium" "Calcium" "Ca")
                                                   ("Magnesium" "Magnésium" "Mg")
                                                   ("Sulfur" "Soufre" "S")
                                                   ("Sodium" "Sodium" "Na")
                                                   ("Chloride" "Chlore" "Cl")
                                                   ("Silicon" "Silicium" "Si")
                                                   ("Iron" "Fer" "Fe")
                                                   ("Zinc" "Zinc" "Zn")
                                                   ("Boron" "Bore" "B")
                                                   ("Manganese" "Manganèse" "Mn")
                                                   ("Copper" "Cuivre" "Cu")
                                                   ("Molybdenum" "Molybdène" "Mo")
                                                   ("Ammonium Nitrogen" "Azote ammoniacal" "NNH4")))
  (with-tx (for ([nutrient-data (in-list default-nutrients)])
             (match-define (list canonical-name french-name formula) nutrient-data)
             (unless (member canonical-name nutrient-names)
               (create-nutrient! canonical-name french-name formula)))))

(define-runtime-path measurement-csv "data/dolibarr_nutrient_measurements_ppm.csv")
(define (seed-historical-nutrient-measurements!)
  (define next-row (make-csv-reader (open-input-file measurement-csv)))
  (define header (next-row))
  (define (row->seed! row)
    (define row-alist (map cons header row))
    (define measured-on (cdr (first row-alist)))
    (define nutrient-values
      (for/hash ([nm (in-list (cdr row-alist))])
        (define formula (car nm))
        (define n (get-nutrient #:formula formula))
        (define v (string->number (cdr nm)))
        (values n v)))
    (create-nutrient-measurement! measured-on nutrient-values))
  (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-runtime-path requirements-csv "data/dolibarr_crop_requirements_ppm.csv")
(define (seed-crop-requirements!)
  (define next-row (make-csv-reader (open-input-file requirements-csv)))
  (define header (next-row))
  (define (row->seed! row)
    (define row-alist (map cons header row))
    (define crop-name (string-downcase (cdr (assoc "Plante" row-alist))))
    (define profile (cdr (assoc "Profil" row-alist)))
    (define nutrient-values
      (for/hash ([crop-requirement (in-list (list-tail row-alist 2))])
        (define formula (car crop-requirement))
        (define n (get-nutrient #:formula formula))
        (define v (string->number (cdr crop-requirement)))
        (values n v)))
    (cond
      [(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)))

(define-runtime-path fertilizer-csv "data/dolibarr_fertilizer_compositions_percentage.csv")
(define (seed-existing-fertilizer-products!)
  (define next-row (make-csv-reader (open-input-file fertilizer-csv)))
  (define header (next-row))
  (define (row->seed! row)
    (define row-alist (map cons header row))
    (define canonical-name (cdr (assoc "Libellé" row-alist)))
    (define brand-name (cdr (assoc "Nom commercial" row-alist)))
    (define nutrient-values
      (for/hash ([fertilizer-component (in-list (list-tail row-alist 3))])
        (define n (get-nutrient #:formula (car fertilizer-component)))
        (define v (string->number (cdr fertilizer-component)))
        (values n v)))
    (create-fertilizer-product! canonical-name brand-name nutrient-values))
  (with-tx (csv-for-each row->seed! next-row)))

(module+ test
  (require "migrations.rkt")
  (connect! #:path 'memory)
  (migrate-all!)
  (seed-database!))
Copyright 2019--2026 Marius PETER