Index: ossp-pkg/quos/TODO RCS File: /v/ossp/cvs/ossp-pkg/quos/TODO,v co -q -kk -p'1.11' '/v/ossp/cvs/ossp-pkg/quos/TODO,v' | diff -u /dev/null - -L'ossp-pkg/quos/TODO' 2>/dev/null --- ossp-pkg/quos/TODO +++ - 2025-04-11 22:02:03.621071448 +0200 @@ -0,0 +1,207 @@ + +- how to implement dynamically adjusting views based + on total number of result records?? + +- sqlite with_v3=yes + perl + perl-dbi with_dbd_sqlite=yes + perl-www + perl-xml + perl-util + apache + +- apache.conf: + Alias /quos/ /u/rse/wrk/ossp/quos/ + + Options +ExecCGI + + +- prepare: + - purpose of all files + - OpenPKG RDF as example + - perldoc IO::File + - perldoc CGI + - perldoc String::Divert + - perldoc DBI + + - design for HTML form for boolean expression based query! + (RT, perldoc DBIx::SearchBuilder) + +- UI Query Part (boolean expression to HTML form): + + Boolean Expression: + expr ::= field op value + | "!" expr + | expr "||" expr + | expr "&&" expr + | "(" expr ")" + field ::= /^[A-Z]+$/ + op ::= "==" | "!=" | "<" | "<=" | ">" | ">=" | "=~" | "!~" + value ::= /^.*$/ + + HTML Form: + ------------------------------ + ( field op value + & field op value ) + & ( | field op value + & field op value + | ! field op value + & ! field op value ) + ------------------------------ + <:NN V:NN UPDATE CLEAR SUBMIT + ------------------------------ + NAME LOAD DELETE + NAME SAVE HYPERLINK + ------------------------------ + +- modules: + + * transformation module: + - format 1: 2d form elements (input after submit of web form) + lo2 lo1 lo0 fn fo fv + +---+ +---+ +---+ +---------+ +---+ +---------+ + 0 ...| | | | | | | grp | |== | | Mail | + +---+ +---+ +---+ +---------+ +---+ +---------+ + +---+ +---+ +---+ +---------+ +---+ +---------+ + 1 ...| | | | ||| | | desc | |=~ | | \bMTA\b | + +---+ +---+ +---+ +---------+ +---+ +---------+ + +---+ +---+ +---+ +---------+ +---+ +---------+ + 2 ...| | |&& | | | | class | |== | | CORE | + +---+ +---+ +---+ +---------+ +---+ +---------+ + +---+ +---+ +---+ +---------+ +---+ +---------+ + 3 ...| | | | ||| | | class | |== | | BASE | + +---+ +---+ +---+ +---------+ +---+ +---------+ + : : : : : : + + fn-0="grp"&fo-0="=="&fv-0="Mail"&lo0-1="||"&fn-1="desc"&fo-1="=~"&fv-1="\bMTA\b" + lo1-2="&&"&fn-2="class"&fo-2="=="&fv-2="CORE"&lo0-3="||"&fn-3="class"&fo-3="=="&fv-3="BASE" + + - format 2a: astract syntax tree for query expression (internal representation) + + function-style: + AND( OR( EQ(grp,"Mail"), + RE(desc,"\bMTA\b") ), + OR( EQ(class,"CORE"), + EQ(class,"BASE") ) ) + + in-core-style: + my $expr = + [ "AND", [ "OR", [ "EQ", "grp", "Mail" ], + [ "RE", "desc", "\bMTA\b"] ], + [ "OR", [ "EQ", "class", "CORE" ], + [ "EQ", "class", "BASE" ] ] ]; + + "print $expr->[2]->[1]->[2];" -> "CORE" + + my $format2b = &transform_tree($expr, \&transform_style_perl); + my $format2c = &transform_tree($expr, \&transform_style_sql); + sub transform_tree { + my ($expr, $style) = @_; + my $str = ''; + my ($op, $a1, $a2) = @{$expr}; + $op = &style($op); + $a1 = ref($a1) ? &style(&transform_tree($a1, $style)) : &style($a1); + $a2 = ref($a2) ? &style(&transform_tree($a2, $style)) : &style($a2); + $str = "$a1 $op $a2"; + return $str; + } + sub transform_style_perl { + my ($token) = @_; + $token =~ s/^AND$/&&/; + $token =~ s/^OR$/||/; + $token =~ s/^EQ$/==/; + $token =~ s/^RE$/=~/; + return $token; + } + sub transform_style_sql { + my ($token) = @_; + $token =~ s/^EQ$/=/; + $token =~ s/^RE$/MATCH/; + return $token; + } + + - format 2b: C-style query expression (input after hyperlink in web page) + + (grp == "Mail" || desc =~ "\bMTA\b") && + (class == "CORE || class == "BASE") + + - format 2c: SQL-style query expression (output for database query) + + (quos.q_grp = 'Mail' OR quos.q_desc MATCH? '\bMTA\b') AND + (quos.q_class = 'CORE' OR quos.q_class = 'BASE') + + * creation of web formular (render query) + sub_render_form (cgi-Object | expression, row, column + +- Parsing CFG: + + OSSP shiela (with tricks) + OSSP ac (uses Parse::RecDescent) + Parse::RecDescent (full featured recursive-descend parsing) + + GENERAL: + config ::= directive(s) + directive ::= word arg ";" + arg ::= "{" config "}" + | word + word ::= m/"[^"]*"/ + | m/'[^']*'/ + | m/[^\s+;]+/ + + SPECIAL: + config ::= directive(s) + directive ::= options + | queries + | views + options ::= "option" "{" options-directive(s) "}" ";" + options-directive ::= webpage + | database + webpage ::= "webpage" word word ";" + database ::= "database" "{" database-directive(s) "}" ";" + database-directive ::= ... + ... + queries ::= group(s) + ... + views ::= view(s) + ... + word ::= m/"[^"]*"/ + | m/'[^']*'/ + | m/[^\s+;]+/ + +- Parsing RDF: + + my $str = ...; # string representation + my $rdf = {}; # AST representation + + $str =~ s/]+)>(.+?)<\/Repository>/&do_repository($rdf, $1, $2)/sge; + sub do_repository { + my ($rdf, $attr, $str) = @_; + my ($name) = ($attr =~ m/rdf:resource="([^"]+)"/s); + $rdf->{$name} = {}; + $str =~ s/]+)>(.+?)<\/rdf:Description>/&do_destription($rdf->{$name}, $1, $2)/sge; + sub do_description { + my ($rdf, $attr, $str) = @_; + $rdf->{...} = ...; + } + } + + 1. geht nur, wenn die Sprache keine rekursiven Elemente enthält, d.h. ein + Element kann nicht in sich selber (in beliebiger Tiefe) vorkommen + (Hinweis: Für Compilerbauer uninteressant) + + 2. Blockstruktur der Sprache wird direkt Substitution+Funktionsaufruf umgesetzt + + 3. Auf jeder Ebene wird die bereits erkannte Information in einer internen + Datenstruktur aufgesammelt ($rdf) + +- Next Steps: + + - openpkg-rdf2sql.pl: + . rdf to AST parsing (subst+func) (1) + . AST to SQL mapping (INSERT...) (2) + + - quos.cgi: + . AST to SQL mapping (WHERE....) (3) + . view part + . result part +