Opened 2 months ago

Last modified 6 weeks ago

#110 new Feature request

Select variant by tag combination instead of format — at Version 4

Reported by: florian Owned by:
Milestone: Mode Menu – Fixes Keywords:
Cc:

Description (last modified by florian)

DE:

  • Florian: technische Idee für Evas Wünsche für das Modus-Menü:
    • Varianten bekommen Tags
    • Formaten ist eine feste Kombi aus Tags zugeordnet
    • Zuordnung von Variante zum Format erfolgt nicht wie bisher fest als Feld, sondern implizit über die Tag-Kombination [Nachtrag: Oder doch wie bisher, damit z.B. der korrekte Editor im Redaktionssystem angezeigt wird. Getagt werden dementsprechend Formate – nicht Varianten.]
    • Das Standard-Format ist das ohne Tags
    • Das kann von Kurs zu Kurs (und ggf. von Instanz zu Instanz) verschieden sein
    • Durch den Format-Bezeichner ist die Handhabung in Luna trotzdem eindeutig
    • Es können auch weiter Plugins für die Handhabung von Formaten mit eindeutiger Bezeichung und Pfad erstellt werden
    • Wirft die Frage auf, ob nicht doch sowas wie partielle Plugins ein zuschaltbares Tag möglich/notwendig sind
    • Vorteil: Tags bändigen elegant die kombinatorische Explosion im Modus-Menü
      • schon 3 zuschaltbare Tags brauchen 8 Varianten!
      • Schalter sind im Grunde Bits, die gesetzt werden; 000 = voreingestelltes Format
    • Ungelöst bliebe aber das "[x] Deutsch [ ] Englisch [ ] Ukrainisch"-Problem
      • Na gut: Dann müsste pro Tag hinterlegt werden, mit welchen nicht kombiniert werden kann
        • oder besser: welche Kombinationen erlaubt sind, per Voreinstellung sind alle ausgeschlossen


To query the database for movies with a certain combination of genres, you can use the following SQL query:

SELECT movies.movie_title
FROM movies
JOIN movie_genre ON movies.identifier = movie_genre.movie_id
JOIN genre ON movie_genre.genre_id = genre.identifier
WHERE genre.genre IN ('scifi', 'comedy')
GROUP BY movies.movie_title
HAVING COUNT(DISTINCT genre.genre) = 2;

This query will list all movies that have exactly the genres 'scifi' and 'comedy' assigned to them and no other genres.

Change History (4)

comment:1 Changed 8 weeks ago by florian

Also:

  • Spalte title aus Tabelle formats entfernen
  • Tabelle tags anlegen
    • um etwa Tippfehlern bei Wiederverwendung vorzubeugen
    • Spalten identifier und title wie bei contents, so kann beliebig und z.B. vorübergehend benannt werden, ohne dass es Probleme gibt
    • weitere Spalten wie etwa lang erübrigen sich, weil das durch das schon durch format festgelegt ist
  • formats.identifier und tags.identifier ist eine many-to-many-Beziehung
    • also eine Tabelle tagging dafür anlegen
Last edited 7 weeks ago by florian (previous) (diff)

comment:2 Changed 8 weeks ago by florian

Erlaubte Kombinationen sind trickreich.

Erster Gedanke ist eine Tabelle combinations(tags.tag, tags.tag), aber das wäre ja many-to-many, und es wären spiegelbildliche Doppeleinträge möglich.

Ich habe den Codegenerator codeium.com zu Rate gezogen.

Der halluzinierte erst, dass PRIMARY KEY (tag1, tag2) reichen würde, um etwa einen Eintrag (tag2, tag1) zu verhindern wenn (tag1, tag2) existiert. Das stimmt aber nicht, zeigt ein Praxistest, zumindest nicht in SQLite.

Damit konfrontiert, folgte eine Entschuldigung, und die alternative Empfehlung war, einen Trigger als Guard zu verwenden:

# Generated by codeium.com
CREATE TRIGGER prevent_duplicate_tags
BEFORE INSERT ON tag_combinations
BEGIN
    SELECT CASE
        WHEN EXISTS (
            SELECT tag1 FROM tag_combinations
            WHERE tag1 = NEW.tag2 AND tag2 = NEW.tag1
        )
        THEN RAISE(ABORT, 'Duplicate tag combination')
    END;
END;

Auch sqlitetutorial.net findet das in Ordnung:

In addition, you use triggers to enforce complex business rules centrally at the database level and prevent invalid transactions.

Mir ist das etwas suspekt, aber vor allem kann dann kein Spiegelbild hinzugefügt werden, was möglicherweise irritieren kann, da es ja im weiteren Sinne kein falscher Eintrag wäre, nur eben redundant.

Alternativ ließe sich die Guard Clause auch im Luna-Code einbauen, aber das trennt es mir wieder zu weit vom Datenmodell.

Was wäre, wenn wir in combinations einfach alles zulassen würden – gibt es dann einen Query, der für ein gegebenes Tag alle erlaubten Tags für Kombinationen liefert? Jawoll:

# Generated by codeium.com
SELECT tag2 AS related_tag
FROM tag_combinations
WHERE tag1 = 'pasta'
UNION
SELECT tag1 AS related_tag
FROM tag_combinations
WHERE tag2 = 'pasta';

Laut sqlitetutorial.net kann das AS related_tag offenbar auch weggelassen werden, es wird dann der Spaltenname aus dem ersten Query genommen.

Vielleicht wäre ein Trigger aber doch nützlich, und zwar beim Löschen. Es mag egal sein, wenn eine Information spiegelbildlich doppelt eingetragen wird – aber wenn die Absicht ist, sie zu entfernen, dann müssen alle Kombinationen entfernt werden. Das ginge durch einen Trigger auf DELETE:

# Generated by codeium.com
CREATE TRIGGER delete_reverse_combination
AFTER DELETE ON tag_combinations
BEGIN
    DELETE FROM tag_combinations
    WHERE tag1 = OLD.tag2 AND tag2 = OLD.tag1;
END;

Das OLD habe ich auf sqlitetutorial.net verifiziert.

comment:3 Changed 8 weeks ago by florian

Oder anders:

Ich erfasse erlaubte Kombinationen gar nicht explizit, sondern implizit.

Heißt: Wenn es kein Format gibt, das gleichzeitig mit Leichte Sprache und Fachquellen anzeigen getagt ist, dann ist diese Kombination auch nicht auswählbar.

Wenn es umgekehrt Formate gibt, von denen eines als Leichte Sprache und ein anderes als Leichte Sprache + Begleitwesen anzeigen getagt ist, dann ist Leichte Sprache anwählbar und dann Begleitwesen anzeigen zuschaltbar.

Das könnte Randfälle produzieren. Was ist etwa, wenn Begleitwesen anzeigen nur in Kombination mit anderen Tags verfügbar ist, aber nicht als einzelnes Tag? Dann könnte ich vom Default nicht Begleitwesen anzeigen zuschalten, erst wenn ein anderes Tag eingeschaltet ist. Wie sähe das UI dafür aus?

Wenn ich mit den Markierungs-Balken operiere, müssten die da bereits aktiv sein.

Am besten mal probieren.

comment:4 Changed 6 weeks ago by florian

Description: modified (diff)
Note: See TracTickets for help on using tickets.