help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Format of lists and alists required for displaying lists of tabulate


From: Jean Louis
Subject: Re: Format of lists and alists required for displaying lists of tabulated data
Date: Sat, 24 Jun 2023 22:19:21 +0300
User-agent: Mutt/2.2.10+64 (b470a9a) (2023-06-05)

* uzibalqa <uzibalqa@proton.me> [2023-06-21 13:46]:

> It works indeed.  But instead of just a dyad (a key and value), I
> want to handle an arbitrary number of values.

I am always inside tabulated-list-mode as I use heavily my software: RCD Notes 
& Hyperscope for GNU Emacs, which may not be easy to install.

So I have made functions making my life easy. Let me point out what I mean.

Let us say I wish to find who introduced the person in the list:

(defun cf-people-jump-to-introducer (&optional id)
  "Jump to introducer of person with ID"
  (interactive)
  (when-tabulated-id "people"
      (let ((introducer (rcd-db-get-entry "people" "people_introducedby" id 
cf-db)))
        (cond (introducer (cf-people-by-id-list (list introducer)))
              (t (rcd-warning-message "Cannot find introducer for person with 
ID %s" id))))))

I am pointing now to the function `cf-people-by-id-list'. The rest is only 
finding the ID of introducer, and then that function is opening that contact of 
introducer.

Let us say I need people by their relation type:

(defun cf-people-by-relation-type (&optional id)
  "List of people by relation type ID."
  (interactive)
  (when-tabulated-id "relationtypes"
      (let* ((id-list (rcd-sql-list "SELECT peoplerelations_people1 
                                       FROM peoplerelations
                                      WHERE peoplerelations_relationtypes = $1" 
                                    cf-db id))
             (relation-name (rcd-db-get-entry "relationtypes" 
"relationtypes_name" id cf-db))
             (title (format "People with relation `%s'" relation-name)))
        (cf-people-by-id-list id-list title))))

Then that function `cf-by-people-id-list` does something more complex:

(defun cf-people-by-id-list (list &optional title refresh-function 
return-function)
  (rcd-db-log-function 'cf-people-by-id-list)
  (let* ((limit (or (cf-user-number-of-latest-entries) cf-people-list-limit))
         (refresh-function (or refresh-function (lambda () 
(cf-people-by-id-list list))))
         (list (cond ((> (length list) limit) (seq-subseq list 0 limit))
                     (t list)))
         (sql-id-list (rcd-sql-id-list list)))
    (cond (list (let ((sql (format "SELECT DISTINCT ON (people_id) 
                                           people_id, 
get_full_contacts_name(people_id), 
                                           coalesce((SELECT 
get_contacts_name(peoplerelations_people2) 
                                                       FROM peoplerelations 
                                                      WHERE 
peoplerelations_people1 = people_id 
                                                   ORDER BY 
peoplerelations_default, peoplerelations_id LIMIT 1),
                                                     '>>>UNKNOWN<<<') 
                                       FROM people 
                                      WHERE people_id IN (%s) 
                                   ORDER BY people_id DESC" sql-id-list))
                      (title (or title "People"))
                      (gc-cons-threshold 500000000))
                  (rcd-message "Fetching list of people")
                  (prog2 (rcd-db-sql-report title sql 
cf-people-tabulated-format-with-people-list "people" nil refresh-function 
'(">>>UNKNOWN<<<") return-function)
                      (rcd-message "Total of %s %s" 
                                   (rcd-propertize-bold (number-to-string 
(length list)))
                                   (rcd-propertize-bold "people")))))
        (t (rcd-warning-message (cond (title (format "NO REPORT FOR: %s" title))
                                      (t "NO REPORT FOR PEOPLE LIST")))))))

So by using that function I am making 2 SQL calls, it could be faster if I am 
not using that function, right now there are no noticable differences.

However, it is not really arbitrary data, a there is format 
`cf-people-tabulated-format-with-people-list' which is always used for table 
`people':

cf-people-tabulated-format-with-people-list ➜ [("ID" 8 
rcd-tabulated-number-as-string-predicate) ("Name" 40 t) ("List of people" 40 t)]

To make it more arbitrary one would need to make dynamic format for
tabulated-list-mode, it means your program should figure out how many
columns are there and what are columns names, and maybe even their
width. I think I do not have that possibility currently.

What I have are database table combined views or "combos", so for each table I 
am sometimes automatically generating the combo view, which has it's ID and 
NAME, and then I can edit the entry with arbitrary number of lines. Not 
arbitrary number of columns, even though that is possible too.

For example, I have the entry like:

 33446      countries                    Country                                
  public  table   maddox     32 kB

then I press "l" for the list, and I get:

 1          AFGHANISTAN
 2          ÅLAND ISLANDS
 3          ALBANIA
 4          ALGERIA
 5          AMERICAN SAMOA
 6          ANDORRA
 7          ANGOLA
 8          ANGUILLA
 9          ANTARCTICA
 10         ANTIGUA AND BARBUDA
 11         ARGENTINA

then on some of those entries I press `e' to edit:

                             ID   5
                        Country   "AMERICAN SAMOA"
                           Code   "AS"
                 Dialing Prefix   1
                      Apostille   nil
                       Offshore   nil
                      Continent   nil
           Company registration   nil
                            CRS   t
                         Tag #1   nil
                         Tag #2   nil
                         Tag #3   nil
                      EU Member   nil
                     Flag image   nil
                       Schengen   nil
                     Flag emoji   nil
             Potential Schengen   nil

so that is arbitrary number of rows, not columns, as in some other list:

 1          Europe
 2          Africa
 3          North America
 4          South America
 5          Asia
 6          Australia
 7          Antarctica

I would get different rows:

                             ID   2
                           Name   "Africa"
                      Area km^2   30370000.0
                    Description   nil

However, in the same manner one can make a function to recognize number of 
columns.


-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]