From 3008eb25f79ef1ed54fcc2b3f5b6635b34394680 Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 19 Oct 2025 21:15:18 +0200 Subject: Absorb existing domain data. --- db/seed.rkt | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 db/seed.rkt (limited to 'db/seed.rkt') diff --git a/db/seed.rkt b/db/seed.rkt new file mode 100644 index 0000000..6b253a6 --- /dev/null +++ b/db/seed.rkt @@ -0,0 +1,137 @@ +#lang racket + +;; Seed the database with default values. + +(provide seed-database!) + +(require csv-reading + "conn.rkt" + "../models/nutrient.rkt" + "../models/nutrient-measurement.rkt" + "../models/crop.rkt" + "../models/crop-requirement.rkt" + "../models/fertilizer-product.rkt") + +(define (seed-database!) + (seed-nutrients!) + (seeded "nutrients") + (seed-historical-nutrient-measurements!) + (seeded "historical nutrient measurements") + (seed-crops!) + (seeded "crops") + (seed-crop-requirements!) + (seeded "crop requirements") + (seed-existing-fertilizer-products!) + (seeded "existing fertilizer products")) + +(define (seeded entity) + (displayln (format "Seeded entity: ~a" entity))) + +(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))))) + +(define (seed-historical-nutrient-measurements!) + (define input-csv "/home/blendux/git/ferti-v2/db/data/dolibarr_nutrient_measurements_ppm.csv") + (define next-row (make-csv-reader (open-input-file input-csv))) + (define header (next-row)) + (define (row->seed! row) + (define row-alist (map cons header row)) + (define measured-on (cdar row-alist)) + (define nutrient-values + (for/list ([nm (in-list (cdr row-alist))]) + (define formula (car nm)) + (define n (get-nutrient #:formula formula)) + (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))) + +(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 (seed-crop-requirements!) + (define input-csv "/home/blendux/git/ferti-v2/db/data/dolibarr_crop_requirements_ppm.csv") + (define next-row (make-csv-reader (open-input-file input-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/list ([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))) + (cons 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 (seed-existing-fertilizer-products!) + (define input-csv "/home/blendux/git/ferti-v2/db/data/dolibarr_fertilizer_compositions_percentage.csv") + (define next-row (make-csv-reader (open-input-file input-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/list ([fertilizer-component (in-list (list-tail row-alist 3))]) + (define formula (car fertilizer-component)) + (define n (get-nutrient #:formula formula)) + (define v (string->number (cdr fertilizer-component))) + (cons n v))) + (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))) + +(module+ test + (require "migrations.rkt") + (connect! #:path "test.sqlite3" + ) + (migrate-all!) + (seed-database!)) -- cgit v1.2.3