Define new classes, begin implementing new protocol

This commit is contained in:
contrapunctus 2022-04-17 13:45:31 +05:30
parent 8f14fbb546
commit 998ea0f94e
1 changed files with 80 additions and 31 deletions

View File

@ -672,7 +672,9 @@ treated as though their time is 00:00:00."
*** task-time-one-day :reader:
#+BEGIN_SRC lisp
(defun task-time-one-day (task &optional (date (date-ts)) (backend (chronometrist-active-backend)))
(defun task-time-one-day (task &optional
(date (date-ts))
(backend (chronometrist-active-backend)))
"Return total time spent on TASK today or on DATE, an ISO-8601 date.
The return value is seconds, as an integer."
(let ((task-events (chronometrist-task-records-for-date backend task date)))
@ -680,8 +682,8 @@ The return value is seconds, as an integer."
(->> (plists-to-durations task-events)
(-reduce #'+)
(truncate))
;; no events for this task on DATE, i.e. no time spent
0)))
;; no events for this task on DATE, i.e. no time spent
0)))
#+END_SRC
*** active-time-on :reader:
@ -948,6 +950,56 @@ return a list of tasks from the active backend."
(or *task-list* task-list (setf task-list (list-tasks backend))))))
#+END_SRC
**** day :class:
#+BEGIN_SRC lisp
(defclass day ()
((properties :initarg :properties :accessor properties)
(date :initarg :date
:accessor date
:type integer
:documentation "The date as an integer representing the UNIX epoch time.")
(intervals :initarg :intervals
:accessor intervals
:documentation "The intervals associated with this day.")
(events :initarg :events
:accessor events
:documentation "The events associated with this day.")))
#+END_SRC
**** interval :class:
#+BEGIN_SRC lisp
(defclass interval ()
((properties :initarg :properties :accessor properties)
(activity :initarg :activity
:accessor activity
:type string
:documentation "The name of the task executed during this interval.")
(start :initarg :start
:accessor start
:type integer
:documentation "The time at which this interval started, as an integer representing the UNIX epoch time.")
(stop :initarg :stop
:accessor stop
:type integer
:documentation "The time at which this interval ended, as an integer representing the UNIX epoch time."))
(:documentation "A time range spent on a specific task, with optional properties."))
#+END_SRC
**** event :class:
#+BEGIN_SRC lisp
(defclass event ()
((properties :initarg :properties :accessor properties)
(name :initarg :name
:accessor name
:type string
:documentation "The name of this event.")
(time :initarg :time
:accessor time
:type integer
:documentation "The time at which this interval started, as an integer representing the UNIX epoch time."))
(:documentation "A named timestamp with optional properties."))
#+END_SRC
**** run-assertions :generic:function:
#+BEGIN_SRC lisp
(defgeneric backend-run-assertions (backend)
@ -981,8 +1033,7 @@ For instance, a file-based backend could be undergoing editing by
a user."))
#+END_SRC
**** file operations
***** create-file :generic:function:
**** create-file :generic:function:
[[file:../tests/tests.org::#tests-backend-create-file][tests]]
#+BEGIN_SRC lisp
@ -992,14 +1043,13 @@ Use FILE as a path, if provided.
Return path of new file if successfully created, and nil if it already exists."))
#+END_SRC
***** latest-date-records :generic:function:
**** get :generic:function:
#+BEGIN_SRC lisp
(defgeneric latest-date-records (backend)
(:documentation "Return intervals of latest day in BACKEND as a tagged list (\"DATE\" PLIST*).
Return nil if BACKEND contains no records."))
(defgeneric get (date backend)
(:documentation "Return day associated with DATE from BACKEND, or nil if no such day exists."))
#+END_SRC
***** insert :generic:function:
**** insert :generic:function:
#+BEGIN_SRC lisp
(defgeneric insert (backend plist &key &allow-other-keys)
(:documentation "Insert PLIST as new record in BACKEND.
@ -1013,7 +1063,7 @@ PLIST may be an interval which crosses days."))
(error "Not a valid plist: %S" plist)))
#+END_SRC
***** remove-last :generic:function:
**** remove-last :generic:function:
#+BEGIN_SRC lisp
(defgeneric remove-last (backend &key &allow-other-keys)
(:documentation "Remove last record from BACKEND.
@ -1021,7 +1071,7 @@ Return non-nil if record is successfully removed.
Signal an error if there is no record to remove."))
#+END_SRC
***** latest-record :generic:function:
**** latest-record :generic:function:
#+BEGIN_SRC lisp
(defgeneric latest-record (backend)
(:documentation "Return the latest record from BACKEND as a plist, or nil if BACKEND contains no records.
@ -1032,7 +1082,7 @@ If the latest record starts on one day and ends on another, the
entire (unsplit) record must be returned."))
#+END_SRC
***** task-records-for-date :generic:function:
**** task-records-for-date :generic:function:
#+BEGIN_SRC lisp
(defgeneric task-records-for-date (backend task date-ts &key &allow-other-keys)
(:documentation "From BACKEND, return records for TASK on DATE-TS as a list of plists.
@ -1047,7 +1097,7 @@ Return nil if BACKEND contains no records."))
(error "date-ts %S is not a `ts' struct" date-ts)))
#+END_SRC
***** replace-last :generic:function:
**** replace-last :generic:function:
#+BEGIN_SRC lisp
(defgeneric replace-last (backend plist &key &allow-other-keys)
(:documentation "Replace last record in BACKEND with PLIST.
@ -1058,14 +1108,14 @@ Return non-nil if successful."))
(error "Not a valid plist: %S" plist)))
#+END_SRC
***** to-file :generic:function:
**** to-file :generic:function:
#+BEGIN_SRC lisp
(defgeneric to-file (input-hash-table output-backend output-file)
(:documentation "Save data from INPUT-HASH-TABLE to OUTPUT-FILE, in OUTPUT-BACKEND format.
Any existing data in OUTPUT-FILE is overwritten."))
#+END_SRC
***** on-add :generic:function:
**** on-add :generic:function:
#+BEGIN_SRC lisp
(defgeneric on-add (backend)
(:documentation "Function called when data is added to BACKEND.
@ -1076,7 +1126,7 @@ backend file).
NEW-DATA is the data that was added."))
#+END_SRC
***** on-modify :generic:function:
**** on-modify :generic:function:
#+BEGIN_SRC lisp
(defgeneric on-modify (backend)
(:documentation "Function called when data in BACKEND is modified (rather than added or removed).
@ -1088,7 +1138,7 @@ OLD-DATA and NEW-DATA is the data before and after the changes,
respectively."))
#+END_SRC
***** on-remove :generic:function:
**** on-remove :generic:function:
#+BEGIN_SRC lisp
(defgeneric on-remove (backend)
(:documentation "Function called when data is removed from BACKEND.
@ -1099,7 +1149,7 @@ the backend file).
OLD-DATA is the data that was modified."))
#+END_SRC
***** on-change :generic:function:
**** on-change :generic:function:
#+BEGIN_SRC lisp
(defgeneric on-change (backend &rest args)
(:documentation "Function to be run when BACKEND changes on disk.
@ -1108,7 +1158,7 @@ This may happen within Chronometrist (e.g. via
backend file)."))
#+END_SRC
***** verify :generic:function:
**** verify :generic:function:
#+BEGIN_SRC lisp
(defgeneric verify (backend)
(:documentation "Check BACKEND for errors in data.
@ -1117,7 +1167,7 @@ Return nil if no errors are found.
If an error is found, return (LINE-NUMBER . COLUMN-NUMBER) for file-based backends."))
#+END_SRC
***** on-file-path-change :generic:function:
**** on-file-path-change :generic:function:
#+BEGIN_SRC lisp
(defgeneric on-file-path-change (backend old-path new-path)
(:documentation "Function run when the value of `file' is changed.
@ -1125,14 +1175,13 @@ OLD-PATH and NEW-PATH are the old and new values of
`file', respectively."))
#+END_SRC
**** memory operations
***** reset-backend :generic:function:
**** reset-backend :generic:function:
#+BEGIN_SRC lisp
(defgeneric reset-backend (backend)
(:documentation "Reset data structures for BACKEND."))
#+END_SRC
***** to-hash-table :generic:function:
**** to-hash-table :generic:function:
#+BEGIN_SRC lisp
(defgeneric to-hash-table (backend)
(:documentation "Return data in BACKEND as a hash table in chronological order.
@ -1141,13 +1190,13 @@ lists of records, represented by plists. Both hash table keys and
hash table values must be in chronological order."))
#+END_SRC
***** to-list :generic:function:
**** to-list :generic:function:
#+BEGIN_SRC lisp
(defgeneric to-list (backend)
(:documentation "Return all records in BACKEND as a list of plists."))
#+END_SRC
***** memory-layer-empty-p :generic:function:
**** memory-layer-empty-p :generic:function:
#+BEGIN_SRC lisp
(defgeneric memory-layer-empty-p (backend)
(:documentation "Return non-nil if memory layer of BACKEND contains no records, else nil."))
@ -2419,13 +2468,13 @@ s-expressions in a text column.")
**** table-function :function:
#+BEGIN_SRC lisp
#+(or)
(defun table-function (table-specification)
(loop for col-spec in *table-specification*
for (sym str) in *table-specification*
(loop ;; for col-spec in *table-specification*
;; for (sym str) in *table-specification*
with date = ()
for task in (chronometrist:task-list)
for index from 1
collect (cond ((eq sym 'index) index)
(()))))
collect (list index task)))
#+END_SRC
**** display