*** /dev/null Sat Nov 23 01:37:31 2024
--- - Sat Nov 23 01:38:04 2024
***************
*** 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/
+ <Directory /u/hms/wrk/ossp/quos/>
+ Options +ExecCGI
+ </Directory>
+
+ - 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([^>]+)>(.+?)<\/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([^>]+)>(.+?)<\/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
+
|