unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Jean Louis <bugs@gnu.support>
To: uzibalqa <uzibalqa@proton.me>
Cc: Christopher Dimech <dimech@gmx.com>,
	Bruno Barbier <brubar.cs@gmail.com>,
	uzibalqa via Users list for the GNU Emacs text editor
	<help-gnu-emacs@gnu.org>
Subject: Re: Format of lists and alists required for displaying lists of tabulated data
Date: Sat, 24 Jun 2023 22:19:21 +0300	[thread overview]
Message-ID: <ZJdBuRHSd8l33wkJ@lco.syogm.com> (raw)
In-Reply-To: <wiRIgoK2Yx3W29Ch3vIODLVsF97uWdTEINEIhzHHHvhanWsbFAbqCqYieTn4414V5PARzL0HFXXPP_QKCNMP_1HSOXqFtxAaxxoUiFUcXPk=@proton.me>

* 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	other threads:[~2023-06-24 19:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-16 21:08 Format of lists and alists required for displaying lists of tabulated data uzibalqa
2023-06-17  7:36 ` Bruno Barbier
2023-06-17 12:33   ` uzibalqa
2023-06-17 20:54     ` Tim Landscheidt
2023-06-18 10:36       ` uzibalqa
2023-06-18 11:29         ` Tim Landscheidt
2023-06-18 13:20           ` uzibalqa
2023-06-18 13:37           ` uzibalqa
2023-06-18 13:51             ` uzibalqa
2023-06-18 15:31     ` Jean Louis
2023-06-18 19:11       ` uzibalqa
2023-06-19 18:46         ` Jean Louis
2023-06-18 19:16       ` Christopher Dimech
2023-06-19 18:49         ` Jean Louis
2023-06-19 18:59           ` uzibalqa
2023-06-21  4:48             ` Jean Louis
2023-06-21 10:45               ` uzibalqa
2023-06-24 19:19                 ` Jean Louis [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZJdBuRHSd8l33wkJ@lco.syogm.com \
    --to=bugs@gnu.support \
    --cc=brubar.cs@gmail.com \
    --cc=dimech@gmx.com \
    --cc=help-gnu-emacs@gnu.org \
    --cc=uzibalqa@proton.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).