Write working function to convert from hash table->SQLite
This commit is contained in:
parent
b141b3b2d1
commit
1f4f018c70
10
TODO.org
10
TODO.org
|
@ -171,7 +171,7 @@ ppp.el doesn't align plist values along the same column. It's also GPL, and I'm
|
|||
: (foo (1 . bar))
|
||||
Yikes!
|
||||
|
||||
** chronometrist [8%]
|
||||
** chronometrist [7%]
|
||||
1. [ ] Add =:stop= time when we call =chronometrist-kv-accept=, not when we quit the key-value prompt with a blank input.
|
||||
* It might be nice to be able to quit =chronometrist-kv-add= with C-g instead, actually.
|
||||
+ =C-g= stops execution of =chronometrist-run-functions-and-clock-in=/=chronometrist-run-functions-and-clock-out=, so they can't reach the calls for =chronometrist-in=/=chronometrist-out=.
|
||||
|
@ -201,8 +201,12 @@ ppp.el doesn't align plist values along the same column. It's also GPL, and I'm
|
|||
11. [ ] Pretty printer - add support for alists as values
|
||||
12. [ ] key-values - make detection of Lisp values more robust.
|
||||
* If the input string can be read in a single call to =read=, treat it as an s-expression; else, use the current heuristics.
|
||||
13. [ ] key-values - create transformer for key-values, to be run before they are added to the file. This will allow users to do cool things like sorting the key-values.
|
||||
|
||||
13. [ ] key-values - create transformer for key-values, to be run before they are added to the file. This will allow users to do things like sorting the key-values.
|
||||
*** Migration [0%]
|
||||
1. [ ] Implement readers (format -> hash table), emitters (hash table -> format), and predicates for each format. Then implement a single =migrate= command to convert between any supported formats.
|
||||
* sounds like a job for EIEIO - each format could be defined as an object, with slots for information such as the file extension.
|
||||
2. [ ] Instead of using =require= for all backends and dependencies, check which backends are loaded, and load dependencies accordingly.
|
||||
3. [ ] Make migration asynchronous, and use output from the sub-process to make a progress indicator.
|
||||
** chronometrist-report [0%]
|
||||
1. [ ] Show week counter and max weeks; don't scroll past first/last weeks
|
||||
2. [ ] Highlight column of current day
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
(require 'chronometrist-common)
|
||||
(require 'chronometrist-time)
|
||||
(require 'chronometrist-plist-pp)
|
||||
(require 'emacsql-sqlite)
|
||||
(require 'emacsql-sqlite3)
|
||||
|
||||
(defvar chronometrist-file)
|
||||
(defvar chronometrist-migrate-table (make-hash-table :test #'equal))
|
||||
|
@ -105,7 +105,7 @@ file names respectively."
|
|||
chronometrist-migrate-table)
|
||||
(save-buffer)))))
|
||||
|
||||
(defvar chronometrist-migrate-db)
|
||||
(defvar chronometrist-migrate-db (emacsql-sqlite3 (locate-user-emacs-file "chronometrist.sqlite")))
|
||||
|
||||
(defun chronometrist-migrate-populate-sexp (in-file)
|
||||
"Read data from IN-FILE to `chronometrist-migrate-table'.
|
||||
|
@ -157,19 +157,37 @@ file names respectively."
|
|||
:values ([(plist-get :na)])]))
|
||||
chronometrist-migrate-table)))
|
||||
|
||||
(cl-loop for events being the hash-values of chronometrist-events do
|
||||
(cl-loop for event in events do
|
||||
(cl-loop for (keyword value) on event by #'cddr do
|
||||
(let* ((pragma (emacsql db [:pragma (funcall table_info events)]))
|
||||
(row-exists-p (cl-loop for list in pragma thereis
|
||||
(eq (--> (symbol-name keyword)
|
||||
(defun chronometrist-migrate-to-sqlite3 ()
|
||||
(cl-loop with count = 0
|
||||
for events being the hash-values of chronometrist-events do
|
||||
(cl-loop for event in events do
|
||||
(let* ((keywords (seq-filter #'keywordp event))
|
||||
(values (seq-remove #'keywordp event))
|
||||
(columns (mapcar (lambda (keyword)
|
||||
(--> (symbol-name keyword)
|
||||
(s-chop-prefix ":" it)
|
||||
(intern it))
|
||||
(second list)))))
|
||||
(unless row-exists-p
|
||||
(emacsql db [:alter-table events :add-column $i1]) keyword)
|
||||
;; FIXME
|
||||
(emacsql db [:insert-into events :values $i1] value)))))
|
||||
;; emacsql seems to automatically
|
||||
;; convert dashes in column names
|
||||
;; to underscores, so we do the
|
||||
;; same, lest we get a "column
|
||||
;; already exists" error
|
||||
(replace-regexp-in-string "-" "_" it)
|
||||
(intern it)))
|
||||
keywords)))
|
||||
;; ensure all keywords in this plist exist as SQL columns
|
||||
(cl-loop for column in columns do
|
||||
(let* ((pragma (emacsql chronometrist-migrate-db [:pragma (funcall table_info events)]))
|
||||
(column-exists (cl-loop for column-spec in pragma thereis
|
||||
(eq column (second column-spec)))))
|
||||
(unless column-exists
|
||||
(emacsql chronometrist-migrate-db [:alter-table events :add-column $i1] column))))
|
||||
(emacsql chronometrist-migrate-db [:insert-into events [$i1] :values $v2]
|
||||
(vconcat columns) (vconcat values)))
|
||||
(incf count)
|
||||
(when (zerop (% count 5))
|
||||
(message "chronometrist-migrate-migrate - %s events converted" count)))
|
||||
finally do
|
||||
(message "chronometrist-migrate - finished converting %s events." count)))
|
||||
|
||||
(defun chronometrist-migrate (input-format output-format &optional input-file output-file)
|
||||
"Migrate a Chronometrist file from INPUT-FORMAT to OUTPUT-FORMAT.
|
||||
|
|
Reference in New Issue