summaryrefslogtreecommitdiffstats
path: root/.config/emacs/jd/jd-gym.el
blob: 2602e3e46ada231d95cd1166aae65c575fc23600 (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
114
115
116
117
118
119
120
;;; jd-gym.el ---  Gym workout manager.
;;; Commentary:
;; It will be a gym workout manager in the future.
;;; code:

(require 'emacsql-sqlite)

(defconst jd-gym/db--tables-schema
  '((workout-plans
     [(id integer :primary-key :autoincrement)
      (name text)])

    (workouts
     [(id integer :primary-key :autoincrement)
      (workout-plan-id integer :not-null)
      (day integer :not-null)
      (month integer :not-null)
      (year integer :not-null)]
     (:foreign-key [workout-plan-id] :references workout-plans [id] :on-delete :cascade))

    (muscle-part
     [(id integer :primary-key :autoincrement)
      (name text :not-null)])

    (exercises
     [(id integer :primary-key :autoincrement)
      (name text :not-null)
      (muscle-part-id integer :not-null)]
     (:foreign-key [muscle-part-id] :references muscle-part [id] :on-delete :cascade))
    
    (workout-plan-exercise-map
     [(id integer :primary-key :autoincrement)
      (week-day integer :not-null)
      (workout-plan-id integer :not-null)
      (exercise-id integer :not-null)]
     (:foreign-key [workout-plan-id] :references workout-plans [id] :on-delete :cascade)
     (:foreign-key [exercise-id] :references exercises [id] :on-delete :cascade))

    (workout-sets
     [(id integer :primary-key :autoincrement)
      (reps integer :not-null)
      (weight integer :not-null)
      (workout-plan-exercise-map-id integer :not-null)
      (comment text)]
     (:foreign-key [workout-plan-exercise-map-id] :references workout-plan-exercise-map [id] :on-delete :cascade))))

(defconst jd-gym/db--test-data
  '((workout-plans
     ([nil "Push pull"]))
    (workouts
     ([nil 1 3 1 2023]))
    (muscle-part
     ([nil "glutes"]
      [nil "chest"]))
    (exercises
     ([nil "Bench press" 2]
      [nil "RDL" 1]))
    (workout-plan-exercise-map
     ([nil 0 1 1] ; Monday, Push pull, Bench press
      [nil 1 1 2] ; Tuesday, Push pull, RDL
      [nil 3 1 1] ; Thursday, Push pull, Bench press
      [nil 4 1 2] ; Friday, Push pull, RDL
      ))
    (workout-sets
     ([nil 7 70 1 "New PR!"]
      [nil 8 110 2 "It was hard!"]))))

(defun jd-gym/db--test-data-insert ()
  "Insert test data to jd-gym database."
  (mapc (lambda (table)
	  (let ((table-name (car table))
		(table-data (cdr table)))
	    (emacsql jd-gym/db--conn [:insert :into $i1
				      :values $v2]
		     table-name table-data)))
	jd-gym/db--test-data))

(defvar jd-gym/db-path "~/Documents/Gym/gym.sqlite"
  "Path can be relative or absolute.")

(defvar jd-gym/db--conn nil
  "Store connection to jd-gym database.")

(defun jd-gym/db--conn-p ()
  "Check if jd-gym is connected to db."
  (and (emacsql-sqlite-connection-p jd-gym/db--conn)
       (emacsql-live-p jd-gym/db--conn)))

(defun jd-gym/db--connect ()
  "Connect to db if there is no connection yet."
  (unless (jd-gym/db--conn-p)
    (setq jd-gym/db--conn (emacsql-sqlite jd-gym/db-path))))

(defun jd-gym/db--close ()
  "Close db connection."
  (when (jd-gym/db--conn-p)
    (emacsql-close jd-gym/db--conn)))

(defun jd-gym/db--init ()
  "Initialize database structure."
  (when (jd-gym/db--conn-p)
    (emacsql jd-gym/db--conn [:pragma (= foreign_keys ON)])
    (emacsql jd-gym/db--conn "PRAGMA foreign_keys=ON")
    (mapc (lambda (table)
	    (let ((table-name (car table))
		  (table-schema (cdr table)))
	      (emacsql jd-gym/db--conn [:create-table $i1 $S2] table-name table-schema)))
	  jd-gym/db--tables-schema)))

(defun jd-gym/db ()
  "Entrypoint to jd-gym db."
  (unless (file-exists-p jd-gym/db-path)
    (jd-gym/db--close)
    (jd-gym/db--connect) ; Restart connection
    (jd-gym/db--init)))


(provide 'jd-gym)

;;; jd-gym.el ends here