Binary file doc/.static/logilab.png has changed
--- a/doc/.static/sphinx-default.css Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,860 +0,0 @@
-/**
- * Sphinx Doc Design
- */
-
-html, body {
- background: white;
-}
-
-body {
- font-family: Verdana, sans-serif;
- font-size: 100%;
- background-color: white;
- color: black;
- margin: 0;
- padding: 0;
-}
-
-/* :::: LAYOUT :::: */
-
-div.logilablogo {
- padding: 10px 10px 10px 10px;
- height:75;
-}
-
-
-div.document {
- background-color: white;
-}
-
-div.documentwrapper {
- float: left;
- width: 100%;
-}
-
-div.bodywrapper {
- margin: 0 0 0 230px;
-}
-
-div.body {
- background-color: white;
- padding: 0 20px 30px 20px;
- border-left:solid;
- border-left-color:#e2e2e2;
- border-left-width:thin;
-}
-
-div.sphinxsidebarwrapper {
- padding: 10px 5px 0 10px;
-}
-
-div.sphinxsidebar {
- float: left;
- width: 230px;
- margin-left: -100%;
- font-size: 90%;
-}
-
-div.clearer {
- clear: both;
-}
-
-div.footer {
- color: #ff4500;
- width: 100%;
- padding: 9px 0 9px 0;
- text-align: center;
- font-size: 75%;
-}
-
-div.footer a {
- color: #ff4500;
- text-decoration: underline;
-}
-
-div.related {
- background-color: #ff7700;
- color: white;
- width: 100%;
- height: 30px;
- line-height: 30px;
- font-size: 90%;
-}
-
-div.related h3 {
- display: none;
-}
-
-div.related ul {
- margin: 0;
- padding: 0 0 0 10px;
- list-style: none;
-}
-
-div.related li {
- display: inline;
-}
-
-div.related li.right {
- float: right;
- margin-right: 5px;
-}
-
-div.related a {
- color: white;
- font-weight:bold;
-}
-
-/* ::: TOC :::: */
-
-div.sphinxsidebar {
- border-style:solid;
- border-color: white;
-/* background-color:#e2e2e2;*/
- padding-bottom:5px;
-}
-
-div.sphinxsidebar h3 {
- font-family: 'Verdanda', sans-serif;
- color: black;
- font-size: 1.2em;
- font-weight: normal;
- margin: 0;
- padding: 0;
- font-weight:bold;
- font-style:italic;
-}
-
-div.sphinxsidebar h4 {
- font-family: 'Verdana', sans-serif;
- color: black;
- font-size: 1.1em;
- font-weight: normal;
- margin: 5px 0 0 0;
- padding: 0;
- font-weight:bold;
- font-style:italic;
-}
-
-div.sphinxsidebar p {
- color: black;
-}
-
-div.sphinxsidebar p.topless {
- margin: 5px 10px 10px 10px;
-}
-
-div.sphinxsidebar ul {
- margin: 10px;
- padding: 0;
- list-style: none;
- color: black;
-}
-
-div.sphinxsidebar ul ul,
-div.sphinxsidebar ul.want-points {
- margin-left: 20px;
- list-style: square;
-}
-
-div.sphinxsidebar ul ul {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-div.sphinxsidebar a {
- color: black;
-}
-
-div.sphinxsidebar form {
- margin-top: 10px;
-}
-
-div.sphinxsidebar input {
- border: 1px solid #e2e2e2;
- font-family: sans-serif;
- font-size: 1em;
- padding-bottom: 5px;
-}
-
-/* :::: MODULE CLOUD :::: */
-div.modulecloud {
- margin: -5px 10px 5px 10px;
- padding: 10px;
- line-height: 160%;
- border: 1px solid #cbe7e5;
- background-color: #f2fbfd;
-}
-
-div.modulecloud a {
- padding: 0 5px 0 5px;
-}
-
-/* :::: SEARCH :::: */
-ul.search {
- margin: 10px 0 0 20px;
- padding: 0;
-}
-
-ul.search li {
- padding: 5px 0 5px 20px;
- background-image: url(file.png);
- background-repeat: no-repeat;
- background-position: 0 7px;
-}
-
-ul.search li a {
- font-weight: bold;
-}
-
-ul.search li div.context {
- color: #888;
- margin: 2px 0 0 30px;
- text-align: left;
-}
-
-ul.keywordmatches li.goodmatch a {
- font-weight: bold;
-}
-
-/* :::: COMMON FORM STYLES :::: */
-
-div.actions {
- padding: 5px 10px 5px 10px;
- border-top: 1px solid #cbe7e5;
- border-bottom: 1px solid #cbe7e5;
- background-color: #e0f6f4;
-}
-
-form dl {
- color: #333;
-}
-
-form dt {
- clear: both;
- float: left;
- min-width: 110px;
- margin-right: 10px;
- padding-top: 2px;
-}
-
-input#homepage {
- display: none;
-}
-
-div.error {
- margin: 5px 20px 0 0;
- padding: 5px;
- border: 1px solid #d00;
- font-weight: bold;
-}
-
-/* :::: INLINE COMMENTS :::: */
-
-div.inlinecomments {
- position: absolute;
- right: 20px;
-}
-
-div.inlinecomments a.bubble {
- display: block;
- float: right;
- background-image: url(style/comment.png);
- background-repeat: no-repeat;
- width: 25px;
- height: 25px;
- text-align: center;
- padding-top: 3px;
- font-size: 0.9em;
- line-height: 14px;
- font-weight: bold;
- color: black;
-}
-
-div.inlinecomments a.bubble span {
- display: none;
-}
-
-div.inlinecomments a.emptybubble {
- background-image: url(style/nocomment.png);
-}
-
-div.inlinecomments a.bubble:hover {
- background-image: url(style/hovercomment.png);
- text-decoration: none;
- color: #3ca0a4;
-}
-
-div.inlinecomments div.comments {
- float: right;
- margin: 25px 5px 0 0;
- max-width: 50em;
- min-width: 30em;
- border: 1px solid #2eabb0;
- background-color: #f2fbfd;
- z-index: 150;
-}
-
-div#comments {
- border: 1px solid #2eabb0;
- margin-top: 20px;
-}
-
-div#comments div.nocomments {
- padding: 10px;
- font-weight: bold;
-}
-
-div.inlinecomments div.comments h3,
-div#comments h3 {
- margin: 0;
- padding: 0;
- background-color: #2eabb0;
- color: white;
- border: none;
- padding: 3px;
-}
-
-div.inlinecomments div.comments div.actions {
- padding: 4px;
- margin: 0;
- border-top: none;
-}
-
-div#comments div.comment {
- margin: 10px;
- border: 1px solid #2eabb0;
-}
-
-div.inlinecomments div.comment h4,
-div.commentwindow div.comment h4,
-div#comments div.comment h4 {
- margin: 10px 0 0 0;
- background-color: #2eabb0;
- color: white;
- border: none;
- padding: 1px 4px 1px 4px;
-}
-
-div#comments div.comment h4 {
- margin: 0;
-}
-
-div#comments div.comment h4 a {
- color: #d5f4f4;
-}
-
-div.inlinecomments div.comment div.text,
-div.commentwindow div.comment div.text,
-div#comments div.comment div.text {
- margin: -5px 0 -5px 0;
- padding: 0 10px 0 10px;
-}
-
-div.inlinecomments div.comment div.meta,
-div.commentwindow div.comment div.meta,
-div#comments div.comment div.meta {
- text-align: right;
- padding: 2px 10px 2px 0;
- font-size: 95%;
- color: #538893;
- border-top: 1px solid #cbe7e5;
- background-color: #e0f6f4;
-}
-
-div.commentwindow {
- position: absolute;
- width: 500px;
- border: 1px solid #cbe7e5;
- background-color: #f2fbfd;
- display: none;
- z-index: 130;
-}
-
-div.commentwindow h3 {
- margin: 0;
- background-color: #2eabb0;
- color: white;
- border: none;
- padding: 5px;
- font-size: 1.5em;
- cursor: pointer;
-}
-
-div.commentwindow div.actions {
- margin: 10px -10px 0 -10px;
- padding: 4px 10px 4px 10px;
- color: #538893;
-}
-
-div.commentwindow div.actions input {
- border: 1px solid #2eabb0;
- background-color: white;
- color: #135355;
- cursor: pointer;
-}
-
-div.commentwindow div.form {
- padding: 0 10px 0 10px;
-}
-
-div.commentwindow div.form input,
-div.commentwindow div.form textarea {
- border: 1px solid #3c9ea2;
- background-color: white;
- color: black;
-}
-
-div.commentwindow div.error {
- margin: 10px 5px 10px 5px;
- background-color: #fbe5dc;
- display: none;
-}
-
-div.commentwindow div.form textarea {
- width: 99%;
-}
-
-div.commentwindow div.preview {
- margin: 10px 0 10px 0;
- background-color: #70d0d4;
- padding: 0 1px 1px 25px;
-}
-
-div.commentwindow div.preview h4 {
- margin: 0 0 -5px -20px;
- padding: 4px 0 0 4px;
- color: white;
- font-size: 1.3em;
-}
-
-div.commentwindow div.preview div.comment {
- background-color: #f2fbfd;
-}
-
-div.commentwindow div.preview div.comment h4 {
- margin: 10px 0 0 0!important;
- padding: 1px 4px 1px 4px!important;
- font-size: 1.2em;
-}
-
-/* :::: SUGGEST CHANGES :::: */
-div#suggest-changes-box input, div#suggest-changes-box textarea {
- border: 1px solid #ccc;
- background-color: white;
- color: black;
-}
-
-div#suggest-changes-box textarea {
- width: 99%;
- height: 400px;
-}
-
-
-/* :::: PREVIEW :::: */
-div.preview {
- background-image: url(style/preview.png);
- padding: 0 20px 20px 20px;
- margin-bottom: 30px;
-}
-
-
-/* :::: INDEX PAGE :::: */
-
-table.contentstable {
- width: 90%;
-}
-
-table.contentstable p.biglink {
- line-height: 150%;
-}
-
-a.biglink {
- font-size: 1.3em;
-}
-
-span.linkdescr {
- font-style: italic;
- padding-top: 5px;
- font-size: 90%;
-}
-
-/* :::: INDEX STYLES :::: */
-
-table.indextable td {
- text-align: left;
- vertical-align: top;
-}
-
-table.indextable dl, table.indextable dd {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-table.indextable tr.pcap {
- height: 10px;
-}
-
-table.indextable tr.cap {
- margin-top: 10px;
- background-color: #f2f2f2;
-}
-
-img.toggler {
- margin-right: 3px;
- margin-top: 3px;
- cursor: pointer;
-}
-
-form.pfform {
- margin: 10px 0 20px 0;
-}
-
-/* :::: GLOBAL STYLES :::: */
-
-.docwarning {
- background-color: #ffe4e4;
- padding: 10px;
- margin: 0 -20px 0 -20px;
- border-bottom: 1px solid #f66;
-}
-
-p.subhead {
- font-weight: bold;
- margin-top: 20px;
-}
-
-a {
- color: black;
- text-decoration: none;
-}
-
-a:hover {
- text-decoration: underline;
-}
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
- font-family: 'Verdana', sans-serif;
- background-color: white;
- font-weight: bold;
- color: black;
- border-bottom: 1px solid #ccc;
- margin: 20px -20px 10px -20px;
- padding: 3px 0 3px 10px;
-}
-
-div.body h1 { margin-top: 0; font-size: 200%; }
-div.body h2 { font-size: 160%; }
-div.body h3 { font-size: 120%; }
-div.body h4 { font-size: 100%; }
-div.body h5 { font-size: 90%; }
-div.body h6 { font-size: 70%; }
-
-a.headerlink {
- color: #c60f0f;
- font-size: 0.8em;
- padding: 0 4px 0 4px;
- text-decoration: none;
- visibility: hidden;
-}
-
-h1:hover > a.headerlink,
-h2:hover > a.headerlink,
-h3:hover > a.headerlink,
-h4:hover > a.headerlink,
-h5:hover > a.headerlink,
-h6:hover > a.headerlink,
-dt:hover > a.headerlink {
- visibility: visible;
-}
-
-a.headerlink:hover {
- background-color: #c60f0f;
- color: white;
-}
-
-div.body p, div.body dd, div.body li {
- text-align: justify;
- line-height: 130%;
-}
-
-div.body p.caption {
- text-align: inherit;
-}
-
-div.body td {
- text-align: left;
-}
-
-ul.fakelist {
- list-style: none;
- margin: 10px 0 10px 20px;
- padding: 0;
-}
-
-.field-list ul {
- padding-left: 1em;
-}
-
-.first {
- margin-top: 0 !important;
-}
-
-/* "Footnotes" heading */
-p.rubric {
- margin-top: 30px;
- font-weight: bold;
-}
-
-/* "Topics" */
-
-div.topic {
- background-color: #eee;
- border: 1px solid #ccc;
- padding: 0 7px 0 7px;
- margin: 10px 0 10px 0;
-}
-
-p.topic-title {
- font-size: 1.1em;
- font-weight: bold;
- margin-top: 10px;
-}
-
-/* Admonitions */
-
-div.admonition {
- margin-top: 10px;
- margin-bottom: 10px;
- padding: 7px;
-}
-
-div.admonition dt {
- font-weight: bold;
-}
-
-div.admonition dl {
- margin-bottom: 0;
-}
-
-div.admonition p {
- display: inline;
-}
-
-div.seealso {
- background-color: #ffc;
- border: 1px solid #ff6;
-}
-
-div.warning {
- background-color: #ffe4e4;
- border: 1px solid #f66;
-}
-
-div.note {
- background-color: #eee;
- border: 1px solid #ccc;
-}
-
-p.admonition-title {
- margin: 0px 10px 5px 0px;
- font-weight: bold;
- display: inline;
-}
-
-p.admonition-title:after {
- content: ":";
-}
-
-div.body p.centered {
- text-align: center;
- margin-top: 25px;
-}
-
-table.docutils {
- border: 0;
-}
-
-table.docutils td, table.docutils th {
- padding: 1px 8px 1px 0;
- border-top: 0;
- border-left: 0;
- border-right: 0;
- border-bottom: 1px solid #aaa;
-}
-
-table.field-list td, table.field-list th {
- border: 0 !important;
-}
-
-table.footnote td, table.footnote th {
- border: 0 !important;
-}
-
-.field-list ul {
- margin: 0;
- padding-left: 1em;
-}
-
-.field-list p {
- margin: 0;
-}
-
-dl {
- margin-bottom: 15px;
- clear: both;
-}
-
-dd p {
- margin-top: 0px;
-}
-
-dd ul, dd table {
- margin-bottom: 10px;
-}
-
-dd {
- margin-top: 3px;
- margin-bottom: 10px;
- margin-left: 30px;
-}
-
-.refcount {
- color: #060;
-}
-
-dt:target,
-.highlight {
- background-color: #fbe54e;
-}
-
-dl.glossary dt {
- font-weight: bold;
- font-size: 1.1em;
-}
-
-th {
- text-align: left;
- padding-right: 5px;
-}
-
-pre {
- padding: 5px;
- background-color: #efc;
- color: #333;
- border: 1px solid #ac9;
- border-left: none;
- border-right: none;
- overflow: auto;
-}
-
-td.linenos pre {
- padding: 5px 0px;
- border: 0;
- background-color: transparent;
- color: #aaa;
-}
-
-table.highlighttable {
- margin-left: 0.5em;
-}
-
-table.highlighttable td {
- padding: 0 0.5em 0 0.5em;
-}
-
-tt {
- background-color: #ecf0f3;
- padding: 0 1px 0 1px;
- font-size: 0.95em;
-}
-
-tt.descname {
- background-color: transparent;
- font-weight: bold;
- font-size: 1.2em;
-}
-
-tt.descclassname {
- background-color: transparent;
-}
-
-tt.xref, a tt {
- background-color: transparent;
- font-weight: bold;
-}
-
-.footnote:target { background-color: #ffa }
-
-h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
- background-color: transparent;
-}
-
-.optional {
- font-size: 1.3em;
-}
-
-.versionmodified {
- font-style: italic;
-}
-
-form.comment {
- margin: 0;
- padding: 10px 30px 10px 30px;
- background-color: #eee;
-}
-
-form.comment h3 {
- background-color: #326591;
- color: white;
- margin: -10px -30px 10px -30px;
- padding: 5px;
- font-size: 1.4em;
-}
-
-form.comment input,
-form.comment textarea {
- border: 1px solid #ccc;
- padding: 2px;
- font-family: sans-serif;
- font-size: 100%;
-}
-
-form.comment input[type="text"] {
- width: 240px;
-}
-
-form.comment textarea {
- width: 100%;
- height: 200px;
- margin-bottom: 10px;
-}
-
-.system-message {
- background-color: #fda;
- padding: 5px;
- border: 3px solid red;
-}
-
-/* :::: PRINT :::: */
-@media print {
- div.document,
- div.documentwrapper,
- div.bodywrapper {
- margin: 0;
- width : 100%;
- }
-
- div.sphinxsidebar,
- div.related,
- div.footer,
- div#comments div.new-comment-box,
- #top-link {
- display: none;
- }
-}
--- a/doc/.templates/layout.html Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-{%- block doctype -%}
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-{%- endblock %}
-{%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %}
-{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
-{%- macro relbar() %}
- <div class="related">
- <h3>Navigation</h3>
- <ul>
- {%- for rellink in rellinks %}
- <li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
- <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags }}"
- accesskey="{{ rellink[2] }}">{{ rellink[3] }}</a>
- {%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
- {%- endfor %}
- {%- block rootrellink %}
- <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
- {%- endblock %}
- {%- for parent in parents %}
- <li><a href="{{ parent.link|e }}" accesskey="U">{{ parent.title }}</a>{{ reldelim1 }}</li>
- {%- endfor %}
- {%- block relbaritems %}{% endblock %}
- </ul>
- </div>
-{%- endmacro %}
-{%- macro sidebar() %}
- {%- if builder != 'htmlhelp' %}
- <div class="sphinxsidebar">
- <div class="sphinxsidebarwrapper">
- {%- block sidebarlogo %}
- {%- if logo %}
- <p class="logo"><img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/></p>
- {%- endif %}
- {%- endblock %}
- {%- block sidebartoc %}
- {%- if display_toc %}
- <h3>Table Of Contents</h3>
- {{ toc }}
- {%- endif %}
- {%- endblock %}
- {%- block sidebarrel %}
- {%- if prev %}
- <h4>Previous topic</h4>
- <p class="topless"><a href="{{ prev.link|e }}" title="previous chapter">{{ prev.title }}</a></p>
- {%- endif %}
- {%- if next %}
- <h4>Next topic</h4>
- <p class="topless"><a href="{{ next.link|e }}" title="next chapter">{{ next.title }}</a></p>
- {%- endif %}
- {%- endblock %}
- {%- if sourcename %}
- <h3>This Page</h3>
- <ul class="this-page-menu">
- {%- if builder == 'web' %}
- <li><a href="#comments">Comments ({{ comments|length }} so far)</a></li>
- <li><a href="{{ pathto('@edit/' + sourcename)|e }}">Suggest Change</a></li>
- <li><a href="{{ pathto('@source/' + sourcename)|e }}">Show Source</a></li>
- {%- elif builder == 'html' %}
- <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}">Show Source</a></li>
- {%- endif %}
- </ul>
- {%- endif %}
- {%- if customsidebar %}
- {{ rendertemplate(customsidebar) }}
- {%- endif %}
- {%- block sidebarsearch %}
- {%- if pagename != "search" %}
- <h3>{{ builder == 'web' and 'Keyword' or 'Quick' }} search</h3>
- <form class="search" action="{{ pathto('search') }}" method="get">
- <input type="text" name="q" size="18" /> <input type="submit" value="Go" />
- <input type="hidden" name="check_keywords" value="yes" />
- <input type="hidden" name="area" value="default" />
- </form>
- {%- if builder == 'web' %}
- <p style="font-size: 90%">Enter a module, class or function name.</p>
- {%- endif %}
- {%- endif %}
- {%- endblock %}
- </div>
- </div>
- {%- endif %}
-{%- endmacro -%}
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- {%- if builder != 'htmlhelp' %}
- {%- set titlesuffix = " — " + docstitle %}
- {%- endif %}
- <title>{{ title|striptags }}{{ titlesuffix }}</title>
- {%- if builder == 'web' %}
- <link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
- if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
- {%- for link, type, title in page_links %}
- <link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
- {%- endfor %}
- {%- else %}
- <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
- <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
- {%- endif %}
- {%- if builder != 'htmlhelp' %}
- <script type="text/javascript">
- var DOCUMENTATION_OPTIONS = {
- URL_ROOT: '{{ pathto("", 1) }}',
- VERSION: '{{ release }}',
- COLLAPSE_MODINDEX: false,
- FILE_SUFFIX: '{{ file_suffix }}'
- };
- </script>
- <script type="text/javascript" src="{{ pathto('_static/jquery.js', 1) }}"></script>
- <script type="text/javascript" src="{{ pathto('_static/interface.js', 1) }}"></script>
- <script type="text/javascript" src="{{ pathto('_static/doctools.js', 1) }}"></script>
- {%- if use_opensearch %}
- <link rel="search" type="application/opensearchdescription+xml"
- title="Search within {{ docstitle }}"
- href="{{ pathto('_static/opensearch.xml', 1) }}"/>
- {%- endif %}
- {%- if favicon %}
- <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
- {%- endif %}
- {%- endif %}
-{%- block rellinks %}
- {%- if hasdoc('about') %}
- <link rel="author" title="About these documents" href="{{ pathto('about') }}" />
- {%- endif %}
- <link rel="contents" title="Global table of contents" href="{{ pathto('contents') }}" />
- <link rel="index" title="Global index" href="{{ pathto('genindex') }}" />
- <link rel="search" title="Search" href="{{ pathto('search') }}" />
- {%- if hasdoc('copyright') %}
- <link rel="copyright" title="Copyright" href="{{ pathto('copyright') }}" />
- {%- endif %}
- <link rel="top" title="{{ docstitle }}" href="{{ pathto('index') }}" />
- {%- if parents %}
- <link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
- {%- endif %}
- {%- if next %}
- <link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
- {%- endif %}
- {%- if prev %}
- <link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
- {%- endif %}
-{%- endblock %}
-{%- block extrahead %}{% endblock %}
- </head>
- <body>
-
-{% block logilablogo %}
-<div class="logilablogo">
- <a class="logogo" href="http://www.logilab.org"><img border="0" src="{{ pathto('_static/logilab.png', 1) }}"/></a>
- </div>
-{% endblock %}
-
-{%- block relbar1 %}{{ relbar() }}{% endblock %}
-
-{%- block sidebar1 %}{# possible location for sidebar #}{% endblock %}
-
-{%- block document %}
- <div class="document">
- <div class="documentwrapper">
- {%- if builder != 'htmlhelp' %}
- <div class="bodywrapper">
- {%- endif %}
- <div class="body">
- {% block body %}{% endblock %}
- </div>
- {%- if builder != 'htmlhelp' %}
- </div>
- {%- endif %}
- </div>
-{%- endblock %}
-
-{%- block sidebar2 %}{{ sidebar() }}{% endblock %}
- <div class="clearer"></div>
- </div>
-
-{%- block relbar2 %}{{ relbar() }}{% endblock %}
-
-{%- block footer %}
- <div class="footer">
- {%- if hasdoc('copyright') %}
- © <a href="{{ pathto('copyright') }}">Copyright</a> {{ copyright }}.
- {%- else %}
- © Copyright {{ copyright }}.
- {%- endif %}
- {%- if last_updated %}
- Last updated on {{ last_updated }}.
- {%- endif %}
- {%- if show_sphinx %}
- Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
- {%- endif %}
- </div>
-{%- endblock %}
- </body>
-</html>
--- a/doc/Makefile Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " pickle to make pickle files (usable by e.g. sphinx-web)"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " changes to make an overview over all changed/added/deprecated items"
- @echo " linkcheck to check all external links for integrity"
-
-clean:
- -rm -rf build/*
-
-html:
- mkdir -p build/html build/doctrees
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
- @echo
- @echo "Build finished. The HTML pages are in build/html."
-
-pickle:
- mkdir -p build/pickle build/doctrees
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
- @echo
- @echo "Build finished; now you can process the pickle files or run"
- @echo " sphinx-web build/pickle"
- @echo "to start the sphinx-web server."
-
-web: pickle
-
-htmlhelp:
- mkdir -p build/htmlhelp build/doctrees
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in build/htmlhelp."
-
-latex:
- mkdir -p build/latex build/doctrees
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
- @echo
- @echo "Build finished; the LaTeX files are in build/latex."
- @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
- "run these through (pdf)latex."
-
-changes:
- mkdir -p build/changes build/doctrees
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
- @echo
- @echo "The overview file is in build/changes."
-
-linkcheck:
- mkdir -p build/linkcheck build/doctrees
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in build/linkcheck/output.txt."
--- a/doc/canonisation.txt Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-Idées sur la canonisation
-=========================
-
-::
-
- from ginco.rql.node_lib import Variable
-
- def sort(canon_dict):
- canon_dict['all_variables'].sort()
- for l in canon_dict['restriction'].values():
- l.sort()
-
-Exemple 1
----------
-
-Formules équivalentes
-`````````````````````
-
-::
-
- Any N, N2 where N is Note, N2 is Note, N ecrit_par P1, P1 nom 'jphc', N2 ecrit_par P2, P2 nom 'ocy' ;
- Any Y, X where X is Note, Y is Note, X ecrit_par P1, P1 nom 'ocy', Y ecrit_par P2, P2 nom 'jphc' ;
-
-Forme canonique
-```````````````
-
-::
-
- N = Variable('N')
- N2 = Variable('N2')
- P1 = Variable('P1')
- P2 = Variable('P2')
-
- canon1 = {
- 'all_variables': [N, N2, P1, P2],
- 'selected' : [N, N2],
- 'restriction' : {'is' : [(N, 'Note'), (N2, 'Note')],
- 'ecrit_par' : [(N, P1), (N2, P2)],
- 'nom' : [(P1, 'jphc'), (P2, 'ocy')]
- }
- }
-
- N.name = 'is_Note:ecrit_par:1' # 1 car c'est la première variable séléctionnée
- N2.name = 'is_Note:ecrit_par:2' # deviner pourquoi 2 ...
- P1.name = 'ecrit_par_jphc'
- P2.name = 'ecrit_par_ocy'
- sort(canon1)
-
- Y = Variable('Y')
- X = Variable('X')
- P1 = Variable('P1')
- P2 = Variable('P2')
-
- canon2 = {
- 'all_variables': [X, Y, P1, P2],
- 'selected' : [Y, X],
- 'restriction' : {'is' : [(X, 'Note'), (Y, 'Note')],
- 'ecrit_par' : [(X, P1), (Y, P2)],
- 'nom' : [(P1, 'ocy'), (P2, 'jphc')]
- }
- }
-
- Y.name = 'is_Note:ecrit_par:1'
- X.name = 'is_Note:ecrit_par:2'
- P1.name = 'ecrit_par_ocy'
- P2.name = 'ecrit_par_jphc'
- sort(canon2)
-
-
- canon2 == canon1
-
-Exemple 2
----------
-
-Formules équivalentes
-`````````````````````
-
-::
-
- Note N WHERE N ecrit_le D, N ecrit_par P, P nom 'jphc', D day > (today-10);
- Note K WHERE K ecrit_le D, K ecrit_par Y, D day > (today-10), Y nom 'jphc';
-
-Forme canonique
-```````````````
-
-::
-
- N = Variable('N')
- D = Variable('D')
- P = Variable('P')
- canon1 = {
- 'all_variables': [N, D, P],
- 'selected' : [N],
- 'restriction' : {'is' : [(N, 'Note')],
- 'day': [(D, '> (today-10)')],
- 'ecrit_le' : [(N, D)],
- 'ecrit_par' : [(N, P)],
- 'nom' : [(P, 'jphc')]
- }
- }
- N.name = 'is_Note:ecrit_le:ecrit_par:1'
- D.name = 'ecrit_le:day_> (today-10)'
- P.name = 'ecrit_par:nom_jphc'
- sort(canon1)
-
-
- K = Variable('K')
- D = Variable('D')
- Y = Variable('Y')
- canon2 = {
- 'all_variables': [K, D, Y],
- 'selected' : [K],
- 'restriction' : {'is' : [(K, 'Note')],
- 'day': [(D, '> (today-10)')],
- 'ecrit_le' : [(K, D)],
- 'ecrit_par' : [(K, Y)],
- 'nom' : [(Y, 'jphc')]
- }
- }
- K.name = 'is_Note:ecrit_le:ecrit_par:1'
- D.name = 'ecrit_le:day_> (today-10)'
- Y.name = 'ecrit_par:nom_jphc'
- sort(canon2)
-
- canon1 == canon2
-
-
-Exemple 3
----------
-
-Formules équivalentes
-`````````````````````
-
-::
-
- Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ludal';
- Note K WHERE K ecrit_le D, K ecrit_par Y, D day > (today -10), Y nom in ('jphc', 'ludal');
-
-Forme canonique
-```````````````
-
-::
-
- N = Variable('N')
- D = Variable('D')
- P = Variable('P')
- canon1 = {
- 'all_variables': [N, D, P],
- 'selected' : [N],
- 'restriction' : {'is' : [(N, 'Note')],
- 'day': [(D, '> (today-10)')],
- 'ecrit_le' : [(N, D)],
- 'ecrit_par' : [(N, P)],
- 'nom' : [(P, 'jphc'), (P, 'ludal')]
- }
- }
- N.name = 'is_Note:ecrit_le:ecrit_par:1'
- D.name = 'ecrit_le:day_> (today-10)'
- P.name = 'ecrit_par:nom_jphc'
- sort(canon1)
-
-
- K = Variable('K')
- D = Variable('D')
- Y = Variable('Y')
- canon2 = {
- 'all_variables': [K, D, Y],
- 'selected' : [K],
- 'restriction' : {'is' : [(K, 'Note')],
- 'day': [(D, '> (today-10)')],
- 'ecrit_le' : [(K, D)],
- 'ecrit_par' : [(K, Y)],
- 'nom' : [(Y, 'jphc'), (Y, 'ludal')]
- }
- }
- K.name = 'is_Note:ecrit_le:ecrit_par:1'
- D.name = 'ecrit_le:day_> (today-10)'
- Y.name = 'ecrit_par:nom_jphc'
- sort(canon2)
-
- canon1 == canon2
-
-
-
-Problèmes
----------
-
-1. Les paires de formules suivantes sont considérées comme identiques par
- l'algorithme ci-dessus alors qu'elles ne le sont pas:
-
-::
-
- Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ludal';
- Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc', P nom 'ludal';
-
- Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P prenom 'ludal';
- Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc', P prenom 'ludal';
-
-donne comme restriction:
-
-::
-
- 'restriction' : {'is' : [(K, 'Note')],
- 'day': [(D, '> (today-10)')],
- 'ecrit_le' : [(K, D)],
- 'ecrit_par' : [(K, Y)],
- 'nom_nom' : [(Y, 'jphc', Y, 'ludal')]
- }
-
-2. risque de collision dans les noms de variables non sélectionnées (un exemple ?).
--- a/doc/conf.py Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# RQL documentation build configuration file, created by
-# sphinx-quickstart on Tue Nov 4 07:54:06 2008.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# The contents of this file are pickled, so don't put values in the namespace
-# that aren't pickleable (module imports are okay, they're removed automatically).
-#
-# All configuration values have a default value; values that are commented out
-# serve to show the default value.
-# copyright 2004-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of rql.
-#
-# rql is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# rql is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with rql. If not, see <http://www.gnu.org/licenses/>.
-
-# If your extensions are in another directory, add it here. If the directory
-# is relative to the documentation root, use os.path.abspath to make it
-# absolute, like shown here.
-# sys.path.append(os.path.abspath('some/directory'))
-
-# General configuration
-# ---------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['.templates']
-
-# The suffix of source filenames.
-source_suffix = '.txt'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General substitutions.
-project = 'RQL'
-copyright = '2008, Sylvain Thenault'
-
-# The default replacements for |version| and |release|, also used in various
-# other places throughout the built documents.
-#
-# The short X.Y version.
-version = '0.20.2'
-# The full version, including alpha/beta/rc tags.
-release = '0.20.2'
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-# today = ''
-# Else, today_fmt is used as the format for a strftime call.
-today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-# unused_docs = []
-
-# List of directories, relative to source directories, that shouldn't be searched
-# for source files.
-# exclude_dirs = []
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-# default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-# add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-# add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-# show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-
-# Options for HTML output
-# -----------------------
-
-# The style sheet to use for HTML and HTML Help pages. A file of that name
-# must exist either in Sphinx' static/ path, or in one of the custom paths
-# given in html_static_path.
-html_style = 'sphinx-default.css'
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-# html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-# html_short_title = None
-
-# The name of an image file (within the static path) to place at the top of
-# the sidebar.
-# html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-# html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['.static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-# html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-# html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-# html_additional_pages = {}
-
-# If false, no module index is generated.
-# html_use_modindex = True
-
-# If false, no index is generated.
-# html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-# html_split_index = False
-
-# If true, the reST sources are included in the HTML build as _sources/<name>.
-# html_copy_source = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-# html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-# html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'RQLdoc'
-
-
-# Options for LaTeX output
-# ------------------------
-
-# The paper size ('letter' or 'a4').
-# latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-# latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, document class [howto/manual]).
-latex_documents = [
- ('index', 'RQL.tex', 'RQL Documentation',
- 'Sylvain Thenault', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-# latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-# latex_use_parts = False
-
-# Additional stuff for the LaTeX preamble.
-# latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-# latex_appendices = []
-
-# If false, no module index is generated.
-# latex_use_modindex = True
--- a/doc/index.txt Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-.. RQL documentation master file, created by sphinx-quickstart on Tue Nov 4 07:54:06 2008.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-Documentation technique de RQL
-==============================
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- specifications_fr.txt
- canonisation.txt
- tutoriel_fr.txt
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
--- a/doc/rql_windows.txt Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-Compiling rql for Windows
-=========================
-
-
-:author: Alexandre Fayolle
-:date: 2009/09/09
-
-RQL can use either logilab.constraint or gecode to perform type
-inference. This document explains how the gecode support can be added
-for the Windows platform.
-
-The short way
--------------
-
-Download and install http://ftp.logilab.org/pub/rql/rql-0.23.0.win32-py2.5.exe
-
-The long way
-------------
-
-Problem statement: we want to use python2.5 on windows. Compiling C
-extensions requires Visual Studio 2003, but Gecode requires Visual
-Studio 2008. So we are stuck with using MinGW, and then again Gecode
-requires gcc 4.2 or later and cygwin to support building.
-But cygwin doesn't come with a mingw enabled gcc 4.x (only 3.x
-available), so some stiching is required.
-
-Dependencies installation
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-* cygwin_: download http://www.cygwin.com/setup.exe, run it and select the following
- packages:
-
- - diffutils
- - perl
- - g++-mingw
- - some text editor of your choice (nano, vim...)
-
-* mingw_: download the following files:
-
- - `gcc-g++-4.4.0-bin <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-bin.tar.gz/download>`_
-
- - `gcc-g++-4.4.0-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-dll.tar.gz/download>`_
-
- - `gcc-core-4.4.0-bin <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-bin.tar.gz/download>`_
-
- - `gcc-core-4.4.0-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-dll.tar.gz/download>`_
-
- - `gmp-4.2.4-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gmp-4.2.4-mingw32-dll.tar.gz/download>`_
-
- - `mpfr-2.4.1-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/mpfr-2.4.1-mingw32-dll.tar.gz/download>`_
-
- - `binutils-2.19.1-bin <http://sourceforge.net/projects/mingw/files/GNU%20Binutils/Current%20Release_%20GNU%20binutils-2.19.1/binutils-2.19.1-mingw32-bin.tar.gz/download>`_
-
- - `w32api-3.13-dev <http://sourceforge.net/projects/mingw/files/MinGW%20API%20for%20MS-Windows/Current%20Release_%20w32api-3.13/w32api-3.13-mingw32-dev.tar.gz/download>`_
-
- - `mingwrt-3.15.2-dev <http://sourceforge.net/projects/mingw/files/MinGW%20Runtime/mingwrt-3.15.2/mingwrt-3.15.2-mingw32-dev.tar.gz/download>`_
-
-
-Create ``c:\MinGW``. Launch a cygwin shell, go to ``/cygdrive/c/MinGW`` and
-untar all the mingw tarballs
-
-Edit ``/etc/profile`` and go to the place where the ``PATH`` environment
-variable is set. Change the line to *prepend*
-``/cygdrive/c/MinGW/bin:/cygdrive/c/MinGW/libexec/mingw32/4.4.0`` to the ``PATH``
-
-* download and untar `Gecode 3.1.0 source distribution <http://www.gecode.org/download/gecode-3.1.0.tar.gz>`_.
-
-
-Compiling gecode
-~~~~~~~~~~~~~~~~
-
-In a cygwin shell, go the the untarred Gecode source directory and run::
-
- $ ./configure --enable-version-specific-runtime-libs \
- --disable-shared --disable-qt --disable-gist \
- --disable-examples --enable-static
-
-Edit gecode/support/config.hpp, and change the line ::
-
- #define GECODE_USE_GETTIMEOFDAY 1
-
-to::
-
- #define GECODE_USE_CLOCK 1
-
-run::
-
- $ make CXXFLAGS="-I. -O1 -DNDEBUG -Wextra -Wall -pipe -ggdb \
- -fno-strict-aliasing -ffast-math -mthreads -DGECODE_BUILD_SUPPORT -static-libgcc"
-
-While this runs, consider renting some Bollywood movie (I enjoyed `this one
-<http://www.imdb.com/title/tt0172684/>`_) and watching it.
-
-
-Compiling the C extension in rql
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-in a Windows shell (aka "DOS Console"), go the the rql directory and
-run::
-
- $ set PATH=%PATH%;c:\MinGW\bin;c:\MinGW\libexec\mingw32\4.4.0
- $ python setup.py build_ext -c mingw32 \
- -Ic:\temp\gecode-3.1.0 \
- -Lc:\temp\gecode-3.1.0
- --in-place
-
-Test
-~~~~
-
-Open a new console (to get the default ``PATH``). Go to the parent
-directory of rql. Launch the Python interpreter, and type::
-
- >>> import rql.analyze
-
-If this works, congratulation, you're done.
-
-
-
-.. _cygwin: http://www.cygwin.com
-.. _mingw: http://www.mingw.org
-
--- a/doc/specifications_en.txt Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,588 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-===================================================
-Specification "Relations Query Language" (Hercules)
-===================================================
-
-Introduction
-============
-
-Goals RQL
----------
-
-The goal is to have a language emphasizing the way of browsing
-relations. As such, attributes will be regarded as cases of
-special relations (in terms of implementation, the user
-language not to see virtually no difference between an attribute and a
-relation).
-
-RQL is inspired by SQL but is the highest level. A knowledge of the
-`CubicWeb` schema defining the application is necessary.
-
-Comparison with existing languages
-----------------------------------
-
-SQL
-```
-RQL builds on the features of SQL but is at a higher level
-(the current implementation of RQL generates SQL). For that it is limited
-to the way of browsing relations and introduces variables.
-The user does not need to know the model underlying SQL, but the `CubicWeb`
-scheam defining the application.
-
-Versa
-`````
-Should I look in more detail, but here is already some ideas for
-the moment ... Versa_ is the language most similar to what we wanted
-to do, but the model underlying data being RDF, there is some
-number of things such as namespaces or handling of the RDF types which
-does not interest us. On the functionality level, Versa_ is very comprehensive
-including through many functions of conversion and basic types manipulation,
-which may need to be guided at one time or another.
-Finally, the syntax is a little esoteric.
-
-See also
-``````````
-RDFQL_
-
-
-The different types of queries
-------------------------------
-
-Search ( `Any`)
- This type of query can extract entities and attributes of entities.
-
-Inserting entities ( `INSERT`)
- This type of query is used to insert new entities in the database. It
- will also create direct relationships entities newly created.
-
-Update entities, relations creation( `SET`)
- This type of query updates existing entities in the database,
- or create relations between existing entities.
-
-Deletion of entities or relationship ( `DELETE`)
- This type of query allows for the removal of entities and relations existing
- in the database.
-
-
-
-Examples
-========
-
-(see the tutorial: ref: `tutorielRQL` for more examples)
-
-Search Query
-------------
-
- [ `DISTINCT`] <entity type> V1 (V2) \ *
- [ `GROUPBY` V1 (V2) \*] [ `ORDERBY` <orderterms>]
- [ `WHERE` <restriction>]
- [ `LIMIT` <value>] [ `OFFSET` <value>]
-
-:entity type:
- Type of selected variables.
- The special type `Any` is equivalent to not specify a type.
-:restriction:
- list of relations to go through whic follow the pattern
- `V1 relation V2 | <static value>`
-:orderterms:
- Definition of the selection order: variable or column number followed by
- sorting method ( `ASC`, `DESC`), ASC is the default.
-:note for grouped queries:
- For grouped queries (e.g., a clause `GROUPBY`), all
- selected variables must be aggregated or grouped.
-
-
-
-- *Search for the object of identifier 53*
- ::
-
- Any WHERE X
- X eid 53
-
-- *Search material such as comics, owned by syt and available*
- ::
-
- WHERE X Document
- X occurence_of F, F class C, C name 'Comics'
- X owned_by U, U login 'syt'
- X available true
-
-- *Looking for people working for eurocopter interested in training*
- ::
-
- Person P WHERE
- P work_for P, S name 'Eurocopter'
- P interested_by T, T name 'training'
-
-- *Search note less than 10 days old written by jphc or ocy*
- ::
-
- Note N WHERE
- N written_on D, D day> (today -10),
- N written_by P, P name 'jphc' or P name 'ocy'
-
-- *Looking for people interested in training or living in Paris*
- ::
-
- Person P WHERE
- (P interested_by T, T name 'training') or
- (P city 'Paris')
-
-- *The name and surname of all people*
- ::
-
- Any N, P WHERE
- X is Person, X name N, X first_name P
-
- Note that the selection of several entities generally force
- the use of "Any" because the type specification applies otherwise
- to all the selected variables. We could write here
- ::
-
- String N, P WHERE
- X is Person, X name N, X first_name P
-
-
-Insertion query
----------------
-
- `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments>
- [ `WHERE` <restriction>]
-
-: assignments:
- list of relations to assign in the form `V1 relationship V2 | <static value>`
-
-The restriction can define variables used in assignments.
-
-Caution, if a restriction is specified, the insertion is done for
-*each line results returned by the restriction*.
-
-- *Insert a new person named 'foo'*
- ::
-
- INSERT Person X: X name 'widget'
-
-- *Insert a new person named 'foo', another called 'nice' and a 'friend' relation
- between them*
- ::
-
- INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y
-
-- *Insert a new person named 'foo' and a 'friend' relation with an existing
- person called 'nice'*
- ::
-
- INSERT Person X: X name 'foo', X friend Y WHERE name 'nice'
-
-Update and relation creation queries
-------------------------------------
- `SET` <assignements>
- [ `WHERE` <restriction>]
-
-Caution, if a restriction is specified, the update is done *for
-each line results returned by the restriction*.
-
-- *Renaming of the person named 'foo' to 'bar' with the first name changed*
- ::
-
- SET X name 'bar', X first_name 'original' where X is Person X name 'foo'
-
-- *Insert a relation of type 'know' between objects linked by
- the relation of type 'friend'*
- ::
-
- SET X know Y WHERE X friend Y
-
-
-Deletion query
---------------
- `DELETE` (<entity type> V) | (V1 relation v2 ),...
- [ `WHERE` <restriction>]
-
-Caution, if a restriction is specified, the deletion is made *for
-each line results returned by the restriction*.
-
-- *Deletion of the person named 'foo'*
- ::
-
- DELETE Person X WHERE X name 'foo'
-
-- *Removal of all relations of type 'friend' from the person named 'foo'*
- ::
-
- DELETE X friend Y WHERE X is Person, X name 'foo'
-
-
-
-Language definition
-===================
-
-Reserved keywords
------------------
-The keywords are not case sensitive.
-
-::
-
- DISTINCT, INSERT, SET, DELETE,
- WHERE, AND, OR, NOT
- IN, LIKE, ILIKE,
- TRUE, FALSE, NULL, TODAY, NOW
- GROUPBY, ORDERBY, ASC, DESC
-
-
-Variables and Typing
---------------------
-
-With RQL, we do not distinguish between entities and attributes. The
-value of an attribute is considered an entity of a particular type (see
-below), linked to one (real) entity by a relation called the name of
-the attribute.
-
-Entities and values to browse and/or select are represented in
-the query by *variables* that must be written in capital letters.
-
-There is a special type **Any**, referring to a non specific type.
-
-We can restrict the possible types for a variable using the
-special relation **is**.
-The possible type(s) for each variable is derived from the schema
-according to the constraints expressed above and thanks to the relations between
-each variable.
-
-Built-in types
-``````````````
-
-The base types supported are string (between double or single quotes),
-integers or floats (the separator is the'.'), dates and
-boolean. We expect to receive a schema in which types String,
-Int, Float, Date and Boolean are defined.
-
-* `String` (literal: between double or single quotes).
-* `Int`, `Float` (separator being'.').
-* `Date`, `Datetime`, `Time` (literal: string YYYY/MM/DD [hh:mm] or keywords
- `TODAY` and `NOW`).
-* `Boolean` (keywords `TRUE` and `FALSE`).
-* `Keyword` NULL.
-
-
-Operators
----------
-
-Logical Operators
-```````````````````
-::
-
- AND, OR, ','
-
-',' is equivalent to 'AND' but with the smallest among the priority
-of logical operators (see :ref:`PriorityOperators`).
-
-Mathematical Operators
-``````````````````````
-::
-
- +, -, *, /
-
-Comparison operators
-````````````````````
-::
-
- =, <, <=, >=, > = ~, IN, LIKE, ILIKE
-
-* The operator `=` is the default operator.
-
-* The operator `LIKE` equivalent to `~=` can be used with the
- special character `%` in a string to indicate that the chain
- must start or finish by a prefix/suffix:
- ::
-
- Any X WHERE X name =~ 'Th%'
- Any X WHERE X name LIKE '%lt'
-
-* The operator `ILIKE` is a case-insensitive version of `LIKE`.
-
-* The operator `IN` provides a list of possible values:
- ::
-
- Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault')
-
-
-XXX nico: A trick <> 'bar' would not it be more convenient than NOT A
-trick 'bar'?
-
-.. _PriorityOperators:
-
-Operators priority
-``````````````````
-
-1. '*', '/'
-
-2. '+', '-'
-
-3. 'and'
-
-4. 'or'
-
-5. ','
-
-
-Advanced Features
------------------
-
-Functions aggregates
-````````````````````
-::
-
- COUNT, MIN, MAX, AVG, SUM
-
-Functions on string
-```````````````````
-::
-
- UPPER, LOWER
-
-Optional relations
-``````````````````
-
-* They allow you to select entities related or not to another.
-
-* You must use the `?` behind the variable to specify that the relation
- toward it is optional:
-
- - Anomalies of a project attached or not to a version ::
-
- Any X, V WHERE X concerns P, P eid 42, X corrected_in V?
-
- - All cards and the project they document if necessary ::
-
- Any C, P WHERE C is Card, P? documented_by C
-
-
-
-BNF grammar
------------
-
-The terminal elements are in capital letters, non-terminal in lowercase.
-The value of the terminal elements (between quotes) is a Python regular
-expression.
-::
-
- statement:: = (select | delete | insert | update) ';'
-
-
- # select specific rules
- select ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
-
- selected_terms ::= expression ( ',' expression)*
-
- group ::= 'GROUPBY' VARIABLE ( ',' VARIABLE)*
-
- sort ::= 'ORDERBY' sort_term ( ',' sort_term)*
-
- sort_term ::= VARIABLE sort_method =?
-
- sort_method ::= 'ASC' | 'DESC'
-
-
- # delete specific rules
- delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
-
-
- # insert specific rules
- insert ::= 'INSERT' variables_declaration ( ':' relations_declaration)? restriction?
-
-
- # update specific rules
- update ::= 'SET' relations_declaration restriction
-
-
- # common rules
- variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
-
- relations_declaration ::= simple_relation (',' simple_relation)*
-
- simple_relation ::= VARIABLE R_TYPE expression
-
- restriction ::= 'WHERE' relations
-
- relations ::= relation (LOGIC_OP relation)*
- | '(' relations')'
-
- relation ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
- | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')'
-
- expression ::= var_or_func_or_const (MATH_OP var_or_func_or_const) *
- | '(' expression ')'
-
- var_or_func_or_const ::= VARIABLE | function | constant
-
- function ::= FUNCTION '(' expression ( ',' expression) * ')'
-
- constant ::= KEYWORD | STRING | FLOAT | INT
-
- # tokens
- LOGIC_OP ::= ',' | 'GOLD' | 'AND'
- MATH_OP ::= '+' | '-' | '/' | '*'
- COMP_OP ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE' | 'ILIKE'
-
- FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'upper' | 'LOWER'
-
- VARIABLE ::= '[A-Z][A-Z0-9]*'
- E_TYPE ::= '[A-Z]\w*'
- R_TYPE ::= '[a-z_]+'
-
- KEYWORD ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
- STRING ::= "'([^'\]|\\.)*'" |'"([^\"]|\\.)*\"'
- FLOAT ::= '\d+\.\d*'
- INT ::= '\d+'
-
-
-Remarks
--------
-
-Sorting and groups
-``````````````````
-
-- For grouped queries (e.g. with a GROUPBY clause), all
- selected variables should be grouped.
-
-- To group and/or sort by attributes, we can do: "X,L user U, U
- login L GROUPBY L, X ORDERBY L"
-
-- If the sorting method (SORT_METHOD) is not specified, then the sorting is
- ascendant.
-
-Negation
-````````
-
-* A query such as `Document X WHERE NOT X owned_by U` means "the
- documents have no relation `owned_by`".
-* But the query `Document X WHERE NOT X owned_by U, U login "syt"`
- means "the documents have no relation `owned_by` with the user
- syt". They may have a relation "owned_by" with another user.
-
-Identity
-````````
-
-You can use the special relation `identity` in a query to
-add an identity constraint between two variables. This is equivalent
-to ``is`` in python::
-
- Any A WHERE A comments B, A identity B
-
-return all objects that comment themselves. The relation
-`identity` is especially useful when defining the rules for securities
-with `RQLExpressions`.
-
-Implementation
-==============
-
-Internal representation (syntactic tree)
-----------------------------------------
-
-The tree research does not contain the selected variables
-(e.g. there is only what follows "WHERE").
-
-The insertion tree does not contain the variables inserted or relations
-defined on these variables (e.g. there is only what follows "WHERE").
-
-The removal tree does not contain the deleted variables and relations
-(e.g. there is only what follows the "WHERE").
-
-The update tree does not contain the variables and relations updated
-(e.g. there is only what follows the "WHERE").
-
-::
-
- Select ((Relationship | And | Gold)?, Group?, Sort?)
- Insert (Relations | And | Gold)?
- Delete (Relationship | And | Gold)?
- Update (Relations | And | Gold)?
-
- And ((Relationship | And | Gold), (Relationship | And | Gold))
- Or ((Relationship | And | Gold), (Relationship | And | Gold))
-
- Relationship ((VariableRef, Comparison))
-
- Comparison ((Function | MathExpression | Keyword | Constant | VariableRef) +)
-
- Function (())
- MathExpression ((MathExpression | Keyword | Constant | VariableRef), (MathExpression | Keyword | Constant | VariableRef))
-
- Group (VariableRef +)
- Sort (SortTerm +)
- SortTerm (VariableRef +)
-
- VariableRef ()
- Variable ()
- Keyword ()
- Constant ()
-
-
-Remarks
--------
-
-- The current implementation does not support linking two relations of type
- 'is' with a OR. I do not think that the negation is supported on this type
- of relation (XXX FIXME to be confirmed).
-
-- Relations defining the variables must be left to those using them.
- For example::
-
- Point P where P abs X, P ord Y, P value X+Y
-
- is valid, but::
-
- Point P where P abs X, P value X+Y, P ord Y
-
- is not.
-
-
-
-Conclusion
-==========
-
-Limitations
------------
-
-It lacks at the moment:
-
-- COALESCE
-
-- restrictions on groups (HAVING)
-
-and certainly other things ...
-
-A disadvantage is that to use this language we must know the
-format used (with real relation names and entities, not those viewing
-in the user interface). On the other hand, we can not really bypass
-that, and it is the job of a user interface to hide the RQL.
-
-
-Topics
-------
-
-It would be convenient to express the schema matching
-relations (non-recursive rules)::
-
- Document class Type <-> Document occurence_of Fiche class Type
- Sheet class Type <-> Form collection Collection class Type
-
-Therefore 1. becomes::
-
- Document X where
- X class C, C name 'Cartoon'
- X owned_by U, U login 'syt'
- X available true
-
-I'm not sure that we should handle this at RQL level ...
-
-There should also be a special relation 'anonymous'.
-
-
-
-.. _Versa: Http://uche.ogbuji.net/tech/rdf/versa/
-.. _RDFQL: Http://www.w3.org/TandS/QL/QL98/pp/rdfquery.html
-
--- a/doc/specifications_fr.txt Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,588 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-=================================================
-Spécification "Relation Query Language" (Hercule)
-=================================================
-
-:Author: Sylvain Thénault
-:Organization: Logilab
-:Version: $Revision: 1.10 $
-:Date: $Date: 2004-05-18 15:04:13 $
-
-Introduction
-============
-
-Objectifs de RQL
-----------------
-
-L'objectif est d'avoir un langage mettant l'accent sur le parcours de
-relations. A ce titre les attributs seront donc considérés comme des cas
-particuliers de relations (au niveau de l'implémentation, l'utilisateur du
-langage ne devant quasiment pas voir de différence entre un attribut et une
-relation).
-
-RQL s'inspire de SQL mais se veut plus haut niveau. Une connaissance du schéma
-Cubicweb définissant l'application est nécessaire.
-
-
-Comparaison avec des langages existants
----------------------------------------
-
-SQL
-```
-RQL s'inspire des fonctionnalités de SQL mais se veut à un plus haut niveau
-(l'implémentation actuelle de RQL génère du SQL). Pour cela il se limite au
-parcours de relations et introduit des variables. L'utilisateur n'a pas besoin
-de connaitre le modèle SQL sous-jacent, mais uniquement le schéma Erudi
-définissant l'application.
-
-Versa
-`````
-Faudrait que je regarde plus en détail, mais voilâ déja quelques idées pour
-l'instant... Versa_ est le langage ressemblant le plus à ce que nous voulions
-faire, mais le modèle de donnée sous-jacent étant du RDF, il y a un certain
-nombre de choses tels que les namespaces ou la manipulation des types RDF qui
-ne nous intéressent pas. Niveau fonctionnalité, Versa_ est très complet
-notamment grâce à de nombreuses fonctions de conversion et de manipulations
-des types de base, dont il faudra peut-être s'inspirer à un moment ou à
-l'autre. Enfin, La syntaxe est un peu ésotérique.
-
-Voir aussi
-``````````
-RDFQL_
-
-
-Les différents types de requêtes
---------------------------------
-
-Recherche (`Any`)
- Ce type de requête permet d'extraire des entités ou des attributs d'entités.
-
-Insertion d'entités (`INSERT`)
- Ce type de requête permet d'insérer de nouvelles entités dans la base. On
- permettra également la création directe de relations sur les entités
- nouvellement créées.
-
-Mise à jour d'entités, création de relations (`SET`)
- Ce type de requête permet de mettre à jours des entités existantes dans la base,
- ou de créer des relations entres des entités existantes.
-
-Suppression d'entités ou de relation (`DELETE`)
- Ce type de requête permet de supprimer des entités et relations existantes dans
- la base.
-
-
-
-Exemples
-========
-
-(voir le tutoriel :ref:`tutorielRQL` pour plus d'exemples)
-
-Requête de recherche
---------------------
-
- [`DISTINCT`] <type d'entité> V1(, V2)\*
- [`GROUPBY` V1(, V2)\*] [`ORDERBY` <orderterms>]
- [`WHERE` <restriction>]
- [`LIMIT` <value>] [`OFFSET` <value>]
-
-:type d'entité:
- Type de la ou des variables séléctionnées.
- Le type spécial `Any`, revient à ne pas spécifier de type.
-:restriction:
- liste des relations à parcourir sous la forme
- `V1 relation V2|<valeur constante>`
-:orderterms:
- Définition de l'ordre de selection : variable ou n° de colonne suivie de la
- méthode de tri (`ASC`, `DESC`), ASC étant la valeur par défaut.
-:note pour les requêtes groupées:
- Pour les requêtes groupées (i.e. avec une clause `GROUPBY`), toutes les
- variables sélectionnée doivent être soit groupée soit aggrégée.
-
-
-
-- *recherche de l'objet ayant l'identifiant 53*
- ::
-
- Any X WHERE
- X eid 53
-
-- *recherche des documents de type bande dessinée, appartenant à syt et disponible*
- ::
-
- Document X WHERE
- X occurence_of F, F class C, C name 'Bande dessinée',
- X owned_by U, U login 'syt',
- X available true
-
-- *recherche des personnes travaillant pour eurocopter intéressé par la formation*
- ::
-
- Personne P WHERE
- P travaille_pour S, S nom 'Eurocopter',
- P interesse_par T, T nom 'formation'
-
-- *recherche des notes de moins de 10 jours écrites par jphc ou ocy*
- ::
-
- Note N WHERE
- N ecrit_le D, D day > (today -10),
- N ecrit_par P, P nom 'jphc' or P nom 'ocy'
-
-- *recherche des personnes intéressées par la formation ou habitant à Paris*
- ::
-
- Personne P WHERE
- (P interesse_par T, T nom 'formation') or
- (P ville 'Paris')
-
-- *Le nom et le prénom de toutes les personnes*
- ::
-
- Any N, P WHERE
- X is Personne, X nom N, X prenom P
-
- On remarquera que la selection de plusieurs entités force généralement
- l'utilisation de "Any", car la spécification de type s'applique sinon
- à toutes les variables séléctionnées. On aurait pu écrire ici
- ::
-
- String N, P WHERE
- X is Personne, X nom N, X prenom P
-
-
-Requête d'insertion
--------------------
- `INSERT` <type d'entité> V1(, <type d'entité> V2)\* `:` <assignements>
- [`WHERE` <restriction>]
-
-:assignements:
- liste des relations à assigner sous la forme `V1 relation V2|<valeur constante>`
-
-La restriction permet de définir des variables utilisées dans les assignements.
-
-Attention, si une restriction est spécifiée, l'insertion est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-- *insertion d'une nouvelle personne nommée 'bidule'*
- ::
-
- INSERT Personne X: X nom 'bidule'
-
-- *insertion d'une nouvelle personne nommée 'bidule', d'une autre nommée 'chouette' et d'une relation 'ami' entre eux*
- ::
-
- INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'chouette', X ami Y
-
-- *insertion d'une nouvelle personne nommée 'bidule' et d'une relation 'ami' avec une personne existante nommée 'chouette'*
- ::
-
- INSERT Personne X: X nom 'bidule', X ami Y WHERE Y nom 'chouette'
-
-
-Requête de mise à jour, création de relations
----------------------------------------------
- `SET` <assignements>
- [`WHERE` <restriction>]
-
-Attention, si une restriction est spécifiée, la mise à jour est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-- *renommage de la personne nommée 'bidule' en 'toto', avec modification du prénom*
- ::
-
- SET X nom 'toto', X prenom 'original' WHERE X is Person, X nom 'bidule'
-
-- *insertion d'une relation de type 'connait' entre les objets reliés par la relation de type 'ami'*
- ::
-
- SET X know Y WHERE X ami Y
-
-
-Requête de suppression
-----------------------
- `DELETE` (<type d''entité> V) | (V1 relation v2),...
- [`WHERE` <restriction>]
-
-Attention, si une restriction est spécifiée, la suppression est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-- *supression de la personne nommé 'toto'*
- ::
-
- DELETE Person X WHERE X nom 'toto'
-
-- *suppression de toutes les relations de type 'ami' partant de la personne nommée 'toto'*
- ::
-
- DELETE X ami Y WHERE X is Person, X nom 'toto'
-
-
-
-Définition du langage
-=====================
-
-Mots clés réservés
-------------------
-Les mots clés ne sont pas sensibles à la casse.
-
-::
-
- DISTINCT, INSERT, SET, DELETE,
- WHERE, AND, OR, NOT
- IN, LIKE, ILIKE,
- TRUE, FALSE, NULL, TODAY, NOW
- GROUPBY, ORDERBY, ASC, DESC
-
-
-Variables et Typage
--------------------
-
-Au niveau de RQL, on ne fait pas de distinction entre entités et attributs. La
-valeur d'un attribut est considérée comme une entité d'un type particulier (voir
-ci-dessous), lié à une (vraie) entité par une relation du nom de l'attribut.
-
-Les entités et valeurs à parcourir et / ou séléctionner sont représentées dans
-la requête par des *variables* qui doivent être écrites en majuscule.
-
-Il existe un type spécial **Any**, revenant à ne pas spécifier de type.
-
-On peut contraindre les types possibles pour une variable à l'aide de la
-relation spéciale **is**.
-
-Le(s) type(s) possible(s) pour chaque variable est déduit du schema en
-fonction des contraintes exprimées ci-dessus et à l'aide des relations entre
-chaque variable.
-
-Types de bases
-``````````````
-
-Les types de bases supportés sont les chaines (entre doubles ou simples quotes),
-les nombres entiers ou flottant (le séparateur étant le '.'), les dates et les
-booléens. On s'attend donc à recevoir un schéma dans lequel les types String,
-Int, Float, Date et Boolean sont définis.
-
-* `String` (litéral: entre doubles ou simples quotes).
-* `Int`, `Float` (le séparateur étant le '.').
-* `Date`, `Datetime`, `Time` (litéral: chaîne YYYY/MM/DD[ hh:mm] ou mots-clés
- `TODAY` et `NOW`).
-* `Boolean` (mots-clés `TRUE` et `FALSE`).
-* mot-clé `NULL`.
-
-
-Opérateurs
-----------
-
-Opérateurs logiques
-```````````````````
-::
-
- AND, OR, ','
-
-"," est équivalent à "AND" mais avec la plus petite priorité parmi les
-opérateurs logiques (voir `Priorité des opérateurs`_).
-
-Opérateurs mathématiques
-````````````````````````
-::
-
- +, -, *, /
-
-Opérateurs de comparaison
-`````````````````````````
-::
-
- =, <, <=, >=, >, ~=, IN, LIKE, ILIKE
-
-* L'opérateur `=` est l'opérateur par défaut.
-
-* L'opérateur `LIKE` équivalent à `~=` permet d'utiliser le caractère `%` dans
- une chaine de caractère pour indiquer que la chaîne doit commencer ou terminer
- par un préfix/suffixe::
-
- Any X WHERE X nom ~= 'Th%'
- Any X WHERE X nom LIKE '%lt'
-
-* L'opérateur `ILIKE` est une version de `LIKE` qui n'est pas sensible à la
- casse.
-
-* L'opérateur `IN` permet de donner une liste de valeurs possibles::
-
- Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
-
-
-XXX nico: A truc <> 'titi' ne serait-il pas plus pratique que NOT A
-truc 'titi' ?
-
-Priorité des opérateurs
-```````````````````````
-
-1. '*', '/'
-
-2. '+', '-'
-
-3. 'and'
-
-4. 'or'
-
-5. ','
-
-
-Fonctionnalités avancées
-------------------------
-
-Fonctions d'aggrégat
-````````````````````
-::
-
- COUNT, MIN, MAX, AVG, SUM
-
-Fonctions sur les chaines
-`````````````````````````
-::
-
- UPPER, LOWER
-
-Relations optionnelles
-``````````````````````
-
-* Elles permettent de sélectionner des entités liées ou non à une autre.
-
-* Il faut utiliser le `?` derrière la variable pour spécifier que la relation
- vers celle-ci est optionnelle :
-
- - Anomalies d'un projet attachées ou non à une version ::
-
- Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
-
- - Toutes les fiches et le projet qu'elles documentent le cas échéant ::
-
- Any C,P WHERE C is Card, P? documented_by C
-
-
-
-Grammaire BNF
--------------
-Les éléments terminaux sont en majuscules, les non-terminaux en minuscule. La
-valeur des éléments terminaux (entre quotes) correspond à une expression
-régulière Python.
-::
-
- statement ::= (select | delete | insert | update) ';'
-
-
- # select specific rules
- select ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
-
- selected_terms ::= expression (',' expression)*
-
- group ::= 'GROUPBY' VARIABLE (',' VARIABLE)*
-
- sort ::= 'ORDERBY' sort_term (',' sort_term)*
-
- sort_term ::= VARIABLE sort_method?
-
- sort_method ::= 'ASC' | 'DESC'
-
-
- # delete specific rules
- delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
-
-
- # insert specific rules
- insert ::= 'INSERT' variables_declaration (':' relations_declaration)? restriction?
-
-
- # update specific rules
- update ::= 'SET' relations_declaration restriction
-
-
- # common rules
- variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
-
- relations_declaration ::= simple_relation (',' simple_relation)*
-
- simple_relation ::= VARIABLE R_TYPE expression
-
- restriction ::= 'WHERE' relations
-
- relations ::= relation (LOGIC_OP relation)*
- | '(' relations ')'
-
- relation ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
- | 'NOT'? VARIABLE R_TYPE 'IN' '(' expression (',' expression)* ')'
-
- expression ::= var_or_func_or_const (MATH_OP var_or_func_or_const)*
- | '(' expression ')'
-
- var_or_func_or_const ::= VARIABLE | function | constant
-
- function ::= FUNCTION '(' expression (',' expression)* ')'
-
- constant ::= KEYWORD | STRING | FLOAT | INT
-
- # tokens
- LOGIC_OP ::= ',' | 'OR' | 'AND'
- MATH_OP ::= '+' | '-' | '/' | '*'
- COMP_OP ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE'
-
- FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER'
-
- VARIABLE ::= '[A-Z][A-Z0-9]*'
- E_TYPE ::= '[A-Z]\w*'
- R_TYPE ::= '[a-z_]+'
-
- KEYWORD ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
- STRING ::= "'([^'\]|\\.)*'" | '"([^\"]|\\.)*\"'
- FLOAT ::= '\d+\.\d*'
- INT ::= '\d+'
-
-
-Remarques
----------
-
-Tri et groupes
-``````````````
-
-- pour les requêtes groupées (i.e. avec une clause GROUPBY), toutes les
- variables sélectionnées doivent être groupées
-
-- pour grouper ou/et trier sur les attributs on peut faire : "X,L user U, U
- login L GROUPBY L,X ORDERBY L"
-
-- si la méthode de tri (SORT_METHOD) n'est pas précisée, alors le tri est
- ascendant.
-
-Négation
-````````
-
-* Une requête du type `Document X WHERE NOT X owned_by U` revient à dire "les
- documents n'ayant pas de relation `owned_by`".
-* En revanche la requête `Document X WHERE NOT X owned_by U, U login "syt"`
- revient à dire "les documents n'ayant pas de relation `owned_by` avec
- l'utilisateur syt". Ils peuvent avoir une relation "owned_by" avec un autre
- utilisateur.
-
-Identité
-````````
-
-On peut utiliser la relation spéciale `identity` dans une requête pour
-rajouter une contrainte d'identité entre deux variables. C'est l'équivalent
-du ``is`` en python::
-
- Any A WHERE A comments B, A identity B
-
-retournerait l'ensemble des objets qui se commentent eux-mêmes. La relation
-`identity` est surtout pratique lors de la définition des règles de sécurités
-avec des `RQLExpressions`.
-
-Implémentation
-==============
-
-Représentation interne (arbre syntaxique)
------------------------------------------
-
-L'arbre de recherche ne contient pas les variables sélectionnées (i.e. on n'y
-trouve que ce qui suit le "WHERE").
-
-L'arbre d'insertion ne contient pas les variables insérées ni les relations
-définies sur ces variables (i.e. on n'y trouve que ce qui suit le
-"WHERE").
-
-L'arbre de suppression ne contient pas les variables ou relations supprimées
-(i.e. on n'y trouve que ce qui suit le "WHERE").
-
-L'arbre de mise à jour ne contient pas les variables ou relations mises à jour
-(i.e. on n'y trouve que ce qui suit le "WHERE").
-
-::
-
- Select ((Relation|And|Or)?, Group?, Sort?)
- Insert (Relation|And|Or)?
- Delete (Relation|And|Or)?
- Update (Relation|And|Or)?
-
- And ((Relation|And|Or), (Relation|And|Or))
- Or ((Relation|And|Or), (Relation|And|Or))
-
- Relation ((VariableRef, Comparison))
-
- Comparison ((Function|MathExpression|Keyword|Constant|VariableRef)+)
-
- Function (())
- MathExpression ((MathExpression|Keyword|Constant|VariableRef), (MathExpression|Keyword|Constant|VariableRef))
-
- Group (VariableRef+)
- Sort (SortTerm+)
- SortTerm (VariableRef+)
-
- VariableRef ()
- Variable ()
- Keyword ()
- Constant ()
-
-
-Remarques
----------
-
-- l'implémentation actuelle ne supporte pas de lier deux relations ayant comme
- type de relation 'is' avec un OR. Je ne pense pas que la négation ne
- soit supportée non plus sur ce type de relation (à confirmer).
-
-- les relations définissant les variables doivent être à gauche de celles les
- utilisant. Par exemple ::
-
- Point P where P abs X, P ord Y, P value X+Y
-
- est valide, mais ::
-
- Point P where P abs X, P value X+Y, P ord Y
-
- ne l'est pas.
-
-
-
-Conclusion
-==========
-
-Limitations
------------
-
-Il manque pour l'instant:
-
-- COALESCE
-
-- restriction sur les groupes (HAVING)
-
-et certainement d'autres choses...
-
-Un inconvénient est que pour utiliser ce langage il faut bien connaitre le
-schéma utilisé (avec les vrais noms de relations et d'entités, pas ceux affichés
-dans l'interface utilisateur). D'un autre coté, on peut pas vraiment contourner
-cela, et c'est le boulot d'une interface utilisateur de cacher le RQL.
-
-
-Sujets de réflexion
--------------------
-
-Il serait pratique de pouvoir exprimer dans le schema des correspondances de
-relations (règles non récursives)::
-
- Document class Type <-> Document occurence_of Fiche class Type
- Fiche class Type <-> Fiche collection Collection class Type
-
-Ainsi 1. devient::
-
- Document X where
- X class C, C name 'Bande dessinée',
- X owned_by U, U login 'syt',
- X available true
-
-Je ne suis cependant pas sûr qu'il faille gérer ça au niveau de RQL...
-
-Il faudrait aussi une relation spéciale 'anonyme'.
-
-
-
-.. _Versa: http://uche.ogbuji.net/tech/rdf/versa/
-.. _RDFQL: http://www.w3.org/TandS/QL/QL98/pp/rdfquery.html
--- a/doc/tutorial_en.txt Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _tutorielRQL:
-
-==================================
-"Relation Query Language" tutorial
-==================================
-
-
-Let's discover RQL with examples.
-
-
-Schema
-------
-
-We will assume the following data model.
-
-:Person:
-
-::
-
- name varchar(64) NOT NULL
- firstname varchar(64)
- sex char(1) DEFAULT 'M'
- title varchar(128)
- email varchar(128)
- web varchar(128)
- tel integer
- birthdate date
-
-
-:Company:
-
-::
-
- name varchar(64)
- web varchar(128)
- tel varchar(15)
- adr varchar(128)
- cp varchar(12)
- city varchar(32)
-
-
-:Workcase:
-
-::
-
- title varchar(128)
- ref varchar(12)
-
-
-:Comment:
-
-::
-
- diem date
- type char(1)
- para varchar(512)
-
-
-with relationships:
-
-::
-
- Person works_for Company
- Person commented_by Comment
- Company commented_by Comment
- Person concerned_by Workcase
- Company concerned_by Workcase
-
-
-Toutes les entités ont un attribut supplémentaire 'eid', permettant
-d'identifier chaque instance de manière unique.
-
-De plus si les métadonnées sont utilisées, vous disposez pour chaque
-type d'entité des relations "creation_date", "modification_date" dont
-l'objet est une entité de type Dates (il y a un "s" pour ne pas avoir
-de conflit avec le type de base "date"), ainsi que de la relation
-"owned_by" dont l'objet est une entité de type Euser. Les schemas
-standards de ces types d'entités sont les suivants :
-
-:Dates:
-
-::
-
- day date
-
-
-:Euser:
-
-::
-
- login varchar(64) not null
- firstname varchar(64)
- surname varchar(64)
- password password
- role choice('admin','user','anonymous') default 'user'
- email varchar(128)
- web varchar(128)
- birthday date
-
-Enfin, il existe la relation spéciale "is" permettant de spécifier le
-type d'une variable.
-
-
-Essentials
-----------
-
-1. *Alls persons*
-
- ::
-
- Person X ;
- or
- Any X WHERE X is Person ;
-
-
-2. *The company namend Logilab*
-
- ::
-
- Company S WHERE S name 'Logilab' ;
-
-
-3. *All entities with a name starting with 'Log'*
-
- ::
-
- Any S WHERE S name LIKE 'Log%' ;
- or
- Any S WHERE S name ~= 'Log%' ;
-
- This query can return entities of type Person and Company.
-
-
-4. *All persons working for a company named Logilab*
-
- ::
-
- Person P WHERE P works_for S, S name "Logilab" ;
- or
- Person P WHERE P works_for S AND S name "Logilab" ;
- or
- Person P WHERE P works_for "Logilab" ;
-
- La dernière forme fonctionne car "nom" est le premier attribut des
- entités de type "Société" XXX nico: toujours vrai ?
-
-
-5. *Companies named Caesium or Logilab*
-
- ::
-
- Company S WHERE S name IN ('Logilab','Caesium') ;
- or
- Company S WHERE S name 'Logilab' OR S name 'Caesium' ;
-
-
-6. *All companies that are not named Caesium or Logilab*
-
- ::
-
- Company S WHERE NOT S name IN ('Logilab','Caesium') ;
- or
- Company S WHERE NOT S name 'Logilab' AND NOT S name 'Caesium' ;
-
-
-7. *All entities commented by the entity number 43*
-
- ::
-
- Any X WHERE X commented_by N, N eid 43 ;
-
-
-8. *All persons sorted by birth date in descending order*
-
- ::
-
- Any X WHERE X is Person, X birthdate D ORDERBY D DESC ;
-
-
-9. *All persons grouped by company*
-
- ::
-
- Person X WHERE X works_for S GROUPBY S,X ;
-
- On note qu'il faut définir une variable pour s'en servir pour le
- groupage. De plus les variables séléctionnées doivent être groupées
- (mais les variables groupées ne doivent pas forcément être sélectionnées).
-
-XXX nico: c'est peu utile comme requête
-
-Exemples avancés
-----------------
-1. *All persons that have an empty name (i.e NULL)*
-
- ::
-
- Person P WHERE P name NULL ;
-
-
-2. *All persons that do not work for a company*
-
- ::
-
- Person P WHERE NOT P works_for S ;
-
-
-3. *All the companies that the person named 'toto' does not work for*
-
- ::
-
- Company S WHERE NOT P works_for S , P name 'toto' ;
- or
- Company S WHERE NOT 'toto' works_for S ;
-
-
-4. *All the entities modified yesterday and today*
-
- ::
-
- Any X WHERE X modification_date <= today, X modification_date >= today - 1
-
-
-5. *All the comments without type that required action within 7 days, sorted by date*
-
-
- ::
-
- Any N, D where N is Comment, N type NULL, N diem D, N diem >= today,
- N diem < today + 7 ORDERBY D
-
-
-6. *All persons that have homonyms (each name listed only once)*
-
- ::
-
- Person X,Y where X name NX, Y name NX, X eid XE, Y eid > XE
--- a/doc/tutoriel_fr.txt Thu Dec 12 03:16:01 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,242 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _tutorielRQL:
-
-============================================
-Tutoriel "Relation Query Language" (Hercule)
-============================================
-
-
-Apprenons RQL par la pratique...
-
-
-
-Schema
-------
-Nous supposerons dans la suite de ce document que le schéma de
-l'application est le suivant. Les différentes entités
-disponibles sont :
-
-:Personne:
-
-::
-
- nom varchar(64) NOT NULL
- prenom varchar(64)
- sexe char(1) DEFAULT 'M'
- promo choice('bon','pasbon')
- titre varchar(128)
- adel varchar(128)
- web varchar(128)
- tel integer
- datenaiss date
-
-
-:Societe:
-
-::
-
- nom varchar(64)
- web varchar(128)
- tel varchar(15)
- adr varchar(128)
- cp varchar(12)
- ville varchar(32)
-
-
-:Affaire:
-
-::
-
- sujet varchar(128)
- ref varchar(12)
-
-
-:Note:
-
-::
-
- diem date
- type char(1)
- para varchar(512)
-
-
-Et les relations entre elles:
-
-::
-
- Person travaille_pour Societe
- Person evaluee_par Note
- Societe evaluee_par Note
- Person concerne_par Note
- Person concerne_par Affaire
- Societe concerne_par Affaire
-
-
-Toutes les entités ont un attribut supplémentaire 'eid', permettant
-d'identifier chaque instance de manière unique.
-
-De plus si les métadonnées sont utilisées, vous disposez pour chaque
-type d'entité des relations "creation_date", "modification_date" dont
-l'objet est une entité de type Dates (il y a un "s" pour ne pas avoir
-de conflit avec le type de base "date"), ainsi que de la relation
-"owned_by" dont l'objet est une entité de type Euser. Les schemas
-standards de ces types d'entités sont les suivants :
-
-:Dates:
-
-::
-
- day date
-
-
-:Euser:
-
-::
-
- login varchar(64) not null
- firstname varchar(64)
- surname varchar(64)
- password password
- role choice('admin','user','anonymous') default 'user'
- email varchar(128)
- web varchar(128)
- birthday date
-
-Enfin, il existe la relation spéciale "is" permettant de spécifier le
-type d'une variable.
-
-
-L'essentiel
------------
-1. *Toutes les personnes*
-
- ::
-
- Personne X ;
- ou
- Any X WHERE X is Personne ;
-
-
-2. *La societé nommé Logilab*
-
- ::
-
- Societe S WHERE S nom 'Logilab' ;
-
-
-3. *Tous les objets ayant un attribut nom commençant par 'Log'*
-
- ::
-
- Any S WHERE S nom LIKE 'Log%' ;
- ou
- Any S WHERE S nom ~= 'Log%' ;
-
- Cette requête peut renvoyer des objets de type personne et de type
- société.
-
-
-4. *Toutes les personnes travaillant pour la société nommé Logilab*
-
- ::
-
- Personne P WHERE P travaille_pour S, S nom "Logilab" ;
- ou
- Personne P WHERE P travaille_pour S AND S nom "Logilab" ;
- ou
- Personne P WHERE P travaille_pour "Logilab" ;
-
- La dernière forme fonctionne car "nom" est le premier attribut des
- entités de type "Société" XXX nico: toujours vrai ?
-
-
-5. *Les societés nommées Caesium ou Logilab*
-
- ::
-
- Societe S WHERE S nom IN ('Logilab','Caesium') ;
- ou
- Societe S WHERE S nom 'Logilab' OR S nom 'Caesium' ;
-
-
-6. *Toutes les societés sauf celles nommées Caesium ou Logilab*
-
- ::
-
- Societe S WHERE NOT S nom IN ('Logilab','Caesium') ;
- ou
- Societe S WHERE NOT S nom 'Logilab' AND NOT S nom 'Caesium' ;
-
-
-7. *Les objets évalués par la note d'identifiant 43*
-
- ::
-
- Any X WHERE X evaluee_par N, N eid 43 ;
-
-
-8. *Toutes les personnes triés par date de naissance dans l'ordre antechronologique*
-
- ::
-
- Any X WHERE X is Personne, X datenaiss D ORDERBY D DESC ;
-
-
-9. *Toutes les personnes groupées par leur société*
-
- ::
-
- Personne X WHERE X travaille_pour S GROUPBY S,X ;
-
- On note qu'il faut définir une variable pour s'en servir pour le
- groupage. De plus les variables séléctionnées doivent être groupées
- (mais les variables groupées ne doivent pas forcément être sélectionnées).
-
-XXX nico: c'est peu utile comme requête
-
-Exemples avancés
-----------------
-1. *Toutes les personnes dont le champ nom n'est pas spécifié (i.e NULL)*
-
- ::
-
- Personne P WHERE P nom NULL ;
-
-
-2. *Toutes les personnes qui ne travaillent pour aucune société*
-
- ::
-
- Personne P WHERE NOT P travaille_pour S ;
-
-
-3. *Toutes les sociétés où la personne nommée toto ne travaille pas*
-
- ::
-
- Societe S WHERE NOT P travaille_pour S , P nom 'toto' ;
- ou
- Societe S WHERE NOT 'toto' travaille_pour S ;
-
-
-4. *Toutes les entités ayant été modifiées entre aujourd'hui et hier*
-
- ::
-
- Any X WHERE X modification_date <= today, X modification_date >= today - 1
-
-
-5. *Toutes les notes n'ayant pas de type et à effectuer dans les 7 jours, triées par date*
-
- ::
-
- Any N, D where N is Note, N type NULL, N diem D, N diem >= today,
- N diem < today + 7 ORDERBY D
-
-
-6. *Les personnes ayant un homonyme (sans doublons)*
-
- ::
-
- Personne X,Y where X nom NX, Y nom NX, X eid XE, Y eid > XE
Binary file docs/.static/logilab.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/.static/sphinx-default.css Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,860 @@
+/**
+ * Sphinx Doc Design
+ */
+
+html, body {
+ background: white;
+}
+
+body {
+ font-family: Verdana, sans-serif;
+ font-size: 100%;
+ background-color: white;
+ color: black;
+ margin: 0;
+ padding: 0;
+}
+
+/* :::: LAYOUT :::: */
+
+div.logilablogo {
+ padding: 10px 10px 10px 10px;
+ height:75;
+}
+
+
+div.document {
+ background-color: white;
+}
+
+div.documentwrapper {
+ float: left;
+ width: 100%;
+}
+
+div.bodywrapper {
+ margin: 0 0 0 230px;
+}
+
+div.body {
+ background-color: white;
+ padding: 0 20px 30px 20px;
+ border-left:solid;
+ border-left-color:#e2e2e2;
+ border-left-width:thin;
+}
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+}
+
+div.clearer {
+ clear: both;
+}
+
+div.footer {
+ color: #ff4500;
+ width: 100%;
+ padding: 9px 0 9px 0;
+ text-align: center;
+ font-size: 75%;
+}
+
+div.footer a {
+ color: #ff4500;
+ text-decoration: underline;
+}
+
+div.related {
+ background-color: #ff7700;
+ color: white;
+ width: 100%;
+ height: 30px;
+ line-height: 30px;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+div.related a {
+ color: white;
+ font-weight:bold;
+}
+
+/* ::: TOC :::: */
+
+div.sphinxsidebar {
+ border-style:solid;
+ border-color: white;
+/* background-color:#e2e2e2;*/
+ padding-bottom:5px;
+}
+
+div.sphinxsidebar h3 {
+ font-family: 'Verdanda', sans-serif;
+ color: black;
+ font-size: 1.2em;
+ font-weight: normal;
+ margin: 0;
+ padding: 0;
+ font-weight:bold;
+ font-style:italic;
+}
+
+div.sphinxsidebar h4 {
+ font-family: 'Verdana', sans-serif;
+ color: black;
+ font-size: 1.1em;
+ font-weight: normal;
+ margin: 5px 0 0 0;
+ padding: 0;
+ font-weight:bold;
+ font-style:italic;
+}
+
+div.sphinxsidebar p {
+ color: black;
+}
+
+div.sphinxsidebar p.topless {
+ margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+ margin: 10px;
+ padding: 0;
+ list-style: none;
+ color: black;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar a {
+ color: black;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #e2e2e2;
+ font-family: sans-serif;
+ font-size: 1em;
+ padding-bottom: 5px;
+}
+
+/* :::: MODULE CLOUD :::: */
+div.modulecloud {
+ margin: -5px 10px 5px 10px;
+ padding: 10px;
+ line-height: 160%;
+ border: 1px solid #cbe7e5;
+ background-color: #f2fbfd;
+}
+
+div.modulecloud a {
+ padding: 0 5px 0 5px;
+}
+
+/* :::: SEARCH :::: */
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li div.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* :::: COMMON FORM STYLES :::: */
+
+div.actions {
+ padding: 5px 10px 5px 10px;
+ border-top: 1px solid #cbe7e5;
+ border-bottom: 1px solid #cbe7e5;
+ background-color: #e0f6f4;
+}
+
+form dl {
+ color: #333;
+}
+
+form dt {
+ clear: both;
+ float: left;
+ min-width: 110px;
+ margin-right: 10px;
+ padding-top: 2px;
+}
+
+input#homepage {
+ display: none;
+}
+
+div.error {
+ margin: 5px 20px 0 0;
+ padding: 5px;
+ border: 1px solid #d00;
+ font-weight: bold;
+}
+
+/* :::: INLINE COMMENTS :::: */
+
+div.inlinecomments {
+ position: absolute;
+ right: 20px;
+}
+
+div.inlinecomments a.bubble {
+ display: block;
+ float: right;
+ background-image: url(style/comment.png);
+ background-repeat: no-repeat;
+ width: 25px;
+ height: 25px;
+ text-align: center;
+ padding-top: 3px;
+ font-size: 0.9em;
+ line-height: 14px;
+ font-weight: bold;
+ color: black;
+}
+
+div.inlinecomments a.bubble span {
+ display: none;
+}
+
+div.inlinecomments a.emptybubble {
+ background-image: url(style/nocomment.png);
+}
+
+div.inlinecomments a.bubble:hover {
+ background-image: url(style/hovercomment.png);
+ text-decoration: none;
+ color: #3ca0a4;
+}
+
+div.inlinecomments div.comments {
+ float: right;
+ margin: 25px 5px 0 0;
+ max-width: 50em;
+ min-width: 30em;
+ border: 1px solid #2eabb0;
+ background-color: #f2fbfd;
+ z-index: 150;
+}
+
+div#comments {
+ border: 1px solid #2eabb0;
+ margin-top: 20px;
+}
+
+div#comments div.nocomments {
+ padding: 10px;
+ font-weight: bold;
+}
+
+div.inlinecomments div.comments h3,
+div#comments h3 {
+ margin: 0;
+ padding: 0;
+ background-color: #2eabb0;
+ color: white;
+ border: none;
+ padding: 3px;
+}
+
+div.inlinecomments div.comments div.actions {
+ padding: 4px;
+ margin: 0;
+ border-top: none;
+}
+
+div#comments div.comment {
+ margin: 10px;
+ border: 1px solid #2eabb0;
+}
+
+div.inlinecomments div.comment h4,
+div.commentwindow div.comment h4,
+div#comments div.comment h4 {
+ margin: 10px 0 0 0;
+ background-color: #2eabb0;
+ color: white;
+ border: none;
+ padding: 1px 4px 1px 4px;
+}
+
+div#comments div.comment h4 {
+ margin: 0;
+}
+
+div#comments div.comment h4 a {
+ color: #d5f4f4;
+}
+
+div.inlinecomments div.comment div.text,
+div.commentwindow div.comment div.text,
+div#comments div.comment div.text {
+ margin: -5px 0 -5px 0;
+ padding: 0 10px 0 10px;
+}
+
+div.inlinecomments div.comment div.meta,
+div.commentwindow div.comment div.meta,
+div#comments div.comment div.meta {
+ text-align: right;
+ padding: 2px 10px 2px 0;
+ font-size: 95%;
+ color: #538893;
+ border-top: 1px solid #cbe7e5;
+ background-color: #e0f6f4;
+}
+
+div.commentwindow {
+ position: absolute;
+ width: 500px;
+ border: 1px solid #cbe7e5;
+ background-color: #f2fbfd;
+ display: none;
+ z-index: 130;
+}
+
+div.commentwindow h3 {
+ margin: 0;
+ background-color: #2eabb0;
+ color: white;
+ border: none;
+ padding: 5px;
+ font-size: 1.5em;
+ cursor: pointer;
+}
+
+div.commentwindow div.actions {
+ margin: 10px -10px 0 -10px;
+ padding: 4px 10px 4px 10px;
+ color: #538893;
+}
+
+div.commentwindow div.actions input {
+ border: 1px solid #2eabb0;
+ background-color: white;
+ color: #135355;
+ cursor: pointer;
+}
+
+div.commentwindow div.form {
+ padding: 0 10px 0 10px;
+}
+
+div.commentwindow div.form input,
+div.commentwindow div.form textarea {
+ border: 1px solid #3c9ea2;
+ background-color: white;
+ color: black;
+}
+
+div.commentwindow div.error {
+ margin: 10px 5px 10px 5px;
+ background-color: #fbe5dc;
+ display: none;
+}
+
+div.commentwindow div.form textarea {
+ width: 99%;
+}
+
+div.commentwindow div.preview {
+ margin: 10px 0 10px 0;
+ background-color: #70d0d4;
+ padding: 0 1px 1px 25px;
+}
+
+div.commentwindow div.preview h4 {
+ margin: 0 0 -5px -20px;
+ padding: 4px 0 0 4px;
+ color: white;
+ font-size: 1.3em;
+}
+
+div.commentwindow div.preview div.comment {
+ background-color: #f2fbfd;
+}
+
+div.commentwindow div.preview div.comment h4 {
+ margin: 10px 0 0 0!important;
+ padding: 1px 4px 1px 4px!important;
+ font-size: 1.2em;
+}
+
+/* :::: SUGGEST CHANGES :::: */
+div#suggest-changes-box input, div#suggest-changes-box textarea {
+ border: 1px solid #ccc;
+ background-color: white;
+ color: black;
+}
+
+div#suggest-changes-box textarea {
+ width: 99%;
+ height: 400px;
+}
+
+
+/* :::: PREVIEW :::: */
+div.preview {
+ background-image: url(style/preview.png);
+ padding: 0 20px 20px 20px;
+ margin-bottom: 30px;
+}
+
+
+/* :::: INDEX PAGE :::: */
+
+table.contentstable {
+ width: 90%;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* :::: INDEX STYLES :::: */
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+form.pfform {
+ margin: 10px 0 20px 0;
+}
+
+/* :::: GLOBAL STYLES :::: */
+
+.docwarning {
+ background-color: #ffe4e4;
+ padding: 10px;
+ margin: 0 -20px 0 -20px;
+ border-bottom: 1px solid #f66;
+}
+
+p.subhead {
+ font-weight: bold;
+ margin-top: 20px;
+}
+
+a {
+ color: black;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+ font-family: 'Verdana', sans-serif;
+ background-color: white;
+ font-weight: bold;
+ color: black;
+ border-bottom: 1px solid #ccc;
+ margin: 20px -20px 10px -20px;
+ padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 120%; }
+div.body h4 { font-size: 100%; }
+div.body h5 { font-size: 90%; }
+div.body h6 { font-size: 70%; }
+
+a.headerlink {
+ color: #c60f0f;
+ font-size: 0.8em;
+ padding: 0 4px 0 4px;
+ text-decoration: none;
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+ visibility: visible;
+}
+
+a.headerlink:hover {
+ background-color: #c60f0f;
+ color: white;
+}
+
+div.body p, div.body dd, div.body li {
+ text-align: justify;
+ line-height: 130%;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+ul.fakelist {
+ list-style: none;
+ margin: 10px 0 10px 20px;
+ padding: 0;
+}
+
+.field-list ul {
+ padding-left: 1em;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+/* "Footnotes" heading */
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+/* "Topics" */
+
+div.topic {
+ background-color: #eee;
+ border: 1px solid #ccc;
+ padding: 0 7px 0 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* Admonitions */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+div.admonition p {
+ display: inline;
+}
+
+div.seealso {
+ background-color: #ffc;
+ border: 1px solid #ff6;
+}
+
+div.warning {
+ background-color: #ffe4e4;
+ border: 1px solid #f66;
+}
+
+div.note {
+ background-color: #eee;
+ border: 1px solid #ccc;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+ display: inline;
+}
+
+p.admonition-title:after {
+ content: ":";
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+table.docutils {
+ border: 0;
+}
+
+table.docutils td, table.docutils th {
+ padding: 1px 8px 1px 0;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+dl {
+ margin-bottom: 15px;
+ clear: both;
+}
+
+dd p {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+.refcount {
+ color: #060;
+}
+
+dt:target,
+.highlight {
+ background-color: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+pre {
+ padding: 5px;
+ background-color: #efc;
+ color: #333;
+ border: 1px solid #ac9;
+ border-left: none;
+ border-right: none;
+ overflow: auto;
+}
+
+td.linenos pre {
+ padding: 5px 0px;
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ margin-left: 0.5em;
+}
+
+table.highlighttable td {
+ padding: 0 0.5em 0 0.5em;
+}
+
+tt {
+ background-color: #ecf0f3;
+ padding: 0 1px 0 1px;
+ font-size: 0.95em;
+}
+
+tt.descname {
+ background-color: transparent;
+ font-weight: bold;
+ font-size: 1.2em;
+}
+
+tt.descclassname {
+ background-color: transparent;
+}
+
+tt.xref, a tt {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+.footnote:target { background-color: #ffa }
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+ background-color: transparent;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+form.comment {
+ margin: 0;
+ padding: 10px 30px 10px 30px;
+ background-color: #eee;
+}
+
+form.comment h3 {
+ background-color: #326591;
+ color: white;
+ margin: -10px -30px 10px -30px;
+ padding: 5px;
+ font-size: 1.4em;
+}
+
+form.comment input,
+form.comment textarea {
+ border: 1px solid #ccc;
+ padding: 2px;
+ font-family: sans-serif;
+ font-size: 100%;
+}
+
+form.comment input[type="text"] {
+ width: 240px;
+}
+
+form.comment textarea {
+ width: 100%;
+ height: 200px;
+ margin-bottom: 10px;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+/* :::: PRINT :::: */
+@media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0;
+ width : 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ div#comments div.new-comment-box,
+ #top-link {
+ display: none;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/.templates/layout.html Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,195 @@
+{%- block doctype -%}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+{%- endblock %}
+{%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %}
+{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
+{%- macro relbar() %}
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ {%- for rellink in rellinks %}
+ <li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
+ <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags }}"
+ accesskey="{{ rellink[2] }}">{{ rellink[3] }}</a>
+ {%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
+ {%- endfor %}
+ {%- block rootrellink %}
+ <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
+ {%- endblock %}
+ {%- for parent in parents %}
+ <li><a href="{{ parent.link|e }}" accesskey="U">{{ parent.title }}</a>{{ reldelim1 }}</li>
+ {%- endfor %}
+ {%- block relbaritems %}{% endblock %}
+ </ul>
+ </div>
+{%- endmacro %}
+{%- macro sidebar() %}
+ {%- if builder != 'htmlhelp' %}
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ {%- block sidebarlogo %}
+ {%- if logo %}
+ <p class="logo"><img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/></p>
+ {%- endif %}
+ {%- endblock %}
+ {%- block sidebartoc %}
+ {%- if display_toc %}
+ <h3>Table Of Contents</h3>
+ {{ toc }}
+ {%- endif %}
+ {%- endblock %}
+ {%- block sidebarrel %}
+ {%- if prev %}
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="{{ prev.link|e }}" title="previous chapter">{{ prev.title }}</a></p>
+ {%- endif %}
+ {%- if next %}
+ <h4>Next topic</h4>
+ <p class="topless"><a href="{{ next.link|e }}" title="next chapter">{{ next.title }}</a></p>
+ {%- endif %}
+ {%- endblock %}
+ {%- if sourcename %}
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ {%- if builder == 'web' %}
+ <li><a href="#comments">Comments ({{ comments|length }} so far)</a></li>
+ <li><a href="{{ pathto('@edit/' + sourcename)|e }}">Suggest Change</a></li>
+ <li><a href="{{ pathto('@source/' + sourcename)|e }}">Show Source</a></li>
+ {%- elif builder == 'html' %}
+ <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}">Show Source</a></li>
+ {%- endif %}
+ </ul>
+ {%- endif %}
+ {%- if customsidebar %}
+ {{ rendertemplate(customsidebar) }}
+ {%- endif %}
+ {%- block sidebarsearch %}
+ {%- if pagename != "search" %}
+ <h3>{{ builder == 'web' and 'Keyword' or 'Quick' }} search</h3>
+ <form class="search" action="{{ pathto('search') }}" method="get">
+ <input type="text" name="q" size="18" /> <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ {%- if builder == 'web' %}
+ <p style="font-size: 90%">Enter a module, class or function name.</p>
+ {%- endif %}
+ {%- endif %}
+ {%- endblock %}
+ </div>
+ </div>
+ {%- endif %}
+{%- endmacro -%}
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ {%- if builder != 'htmlhelp' %}
+ {%- set titlesuffix = " — " + docstitle %}
+ {%- endif %}
+ <title>{{ title|striptags }}{{ titlesuffix }}</title>
+ {%- if builder == 'web' %}
+ <link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
+ if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
+ {%- for link, type, title in page_links %}
+ <link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
+ {%- endfor %}
+ {%- else %}
+ <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+ <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
+ {%- endif %}
+ {%- if builder != 'htmlhelp' %}
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '{{ pathto("", 1) }}',
+ VERSION: '{{ release }}',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '{{ file_suffix }}'
+ };
+ </script>
+ <script type="text/javascript" src="{{ pathto('_static/jquery.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/interface.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/doctools.js', 1) }}"></script>
+ {%- if use_opensearch %}
+ <link rel="search" type="application/opensearchdescription+xml"
+ title="Search within {{ docstitle }}"
+ href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+ {%- endif %}
+ {%- if favicon %}
+ <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
+ {%- endif %}
+ {%- endif %}
+{%- block rellinks %}
+ {%- if hasdoc('about') %}
+ <link rel="author" title="About these documents" href="{{ pathto('about') }}" />
+ {%- endif %}
+ <link rel="contents" title="Global table of contents" href="{{ pathto('contents') }}" />
+ <link rel="index" title="Global index" href="{{ pathto('genindex') }}" />
+ <link rel="search" title="Search" href="{{ pathto('search') }}" />
+ {%- if hasdoc('copyright') %}
+ <link rel="copyright" title="Copyright" href="{{ pathto('copyright') }}" />
+ {%- endif %}
+ <link rel="top" title="{{ docstitle }}" href="{{ pathto('index') }}" />
+ {%- if parents %}
+ <link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
+ {%- endif %}
+ {%- if next %}
+ <link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
+ {%- endif %}
+ {%- if prev %}
+ <link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
+ {%- endif %}
+{%- endblock %}
+{%- block extrahead %}{% endblock %}
+ </head>
+ <body>
+
+{% block logilablogo %}
+<div class="logilablogo">
+ <a class="logogo" href="http://www.logilab.org"><img border="0" src="{{ pathto('_static/logilab.png', 1) }}"/></a>
+ </div>
+{% endblock %}
+
+{%- block relbar1 %}{{ relbar() }}{% endblock %}
+
+{%- block sidebar1 %}{# possible location for sidebar #}{% endblock %}
+
+{%- block document %}
+ <div class="document">
+ <div class="documentwrapper">
+ {%- if builder != 'htmlhelp' %}
+ <div class="bodywrapper">
+ {%- endif %}
+ <div class="body">
+ {% block body %}{% endblock %}
+ </div>
+ {%- if builder != 'htmlhelp' %}
+ </div>
+ {%- endif %}
+ </div>
+{%- endblock %}
+
+{%- block sidebar2 %}{{ sidebar() }}{% endblock %}
+ <div class="clearer"></div>
+ </div>
+
+{%- block relbar2 %}{{ relbar() }}{% endblock %}
+
+{%- block footer %}
+ <div class="footer">
+ {%- if hasdoc('copyright') %}
+ © <a href="{{ pathto('copyright') }}">Copyright</a> {{ copyright }}.
+ {%- else %}
+ © Copyright {{ copyright }}.
+ {%- endif %}
+ {%- if last_updated %}
+ Last updated on {{ last_updated }}.
+ {%- endif %}
+ {%- if show_sphinx %}
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
+ {%- endif %}
+ </div>
+{%- endblock %}
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/Makefile Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,70 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " pickle to make pickle files (usable by e.g. sphinx-web)"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " changes to make an overview over all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+
+clean:
+ -rm -rf build/*
+
+html:
+ mkdir -p build/html build/doctrees
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
+ @echo
+ @echo "Build finished. The HTML pages are in build/html."
+
+pickle:
+ mkdir -p build/pickle build/doctrees
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files or run"
+ @echo " sphinx-web build/pickle"
+ @echo "to start the sphinx-web server."
+
+web: pickle
+
+htmlhelp:
+ mkdir -p build/htmlhelp build/doctrees
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in build/htmlhelp."
+
+latex:
+ mkdir -p build/latex build/doctrees
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in build/latex."
+ @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+ "run these through (pdf)latex."
+
+changes:
+ mkdir -p build/changes build/doctrees
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
+ @echo
+ @echo "The overview file is in build/changes."
+
+linkcheck:
+ mkdir -p build/linkcheck build/doctrees
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in build/linkcheck/output.txt."
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/canonisation.txt Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,210 @@
+Idées sur la canonisation
+=========================
+
+::
+
+ from ginco.rql.node_lib import Variable
+
+ def sort(canon_dict):
+ canon_dict['all_variables'].sort()
+ for l in canon_dict['restriction'].values():
+ l.sort()
+
+Exemple 1
+---------
+
+Formules équivalentes
+`````````````````````
+
+::
+
+ Any N, N2 where N is Note, N2 is Note, N ecrit_par P1, P1 nom 'jphc', N2 ecrit_par P2, P2 nom 'ocy' ;
+ Any Y, X where X is Note, Y is Note, X ecrit_par P1, P1 nom 'ocy', Y ecrit_par P2, P2 nom 'jphc' ;
+
+Forme canonique
+```````````````
+
+::
+
+ N = Variable('N')
+ N2 = Variable('N2')
+ P1 = Variable('P1')
+ P2 = Variable('P2')
+
+ canon1 = {
+ 'all_variables': [N, N2, P1, P2],
+ 'selected' : [N, N2],
+ 'restriction' : {'is' : [(N, 'Note'), (N2, 'Note')],
+ 'ecrit_par' : [(N, P1), (N2, P2)],
+ 'nom' : [(P1, 'jphc'), (P2, 'ocy')]
+ }
+ }
+
+ N.name = 'is_Note:ecrit_par:1' # 1 car c'est la première variable séléctionnée
+ N2.name = 'is_Note:ecrit_par:2' # deviner pourquoi 2 ...
+ P1.name = 'ecrit_par_jphc'
+ P2.name = 'ecrit_par_ocy'
+ sort(canon1)
+
+ Y = Variable('Y')
+ X = Variable('X')
+ P1 = Variable('P1')
+ P2 = Variable('P2')
+
+ canon2 = {
+ 'all_variables': [X, Y, P1, P2],
+ 'selected' : [Y, X],
+ 'restriction' : {'is' : [(X, 'Note'), (Y, 'Note')],
+ 'ecrit_par' : [(X, P1), (Y, P2)],
+ 'nom' : [(P1, 'ocy'), (P2, 'jphc')]
+ }
+ }
+
+ Y.name = 'is_Note:ecrit_par:1'
+ X.name = 'is_Note:ecrit_par:2'
+ P1.name = 'ecrit_par_ocy'
+ P2.name = 'ecrit_par_jphc'
+ sort(canon2)
+
+
+ canon2 == canon1
+
+Exemple 2
+---------
+
+Formules équivalentes
+`````````````````````
+
+::
+
+ Note N WHERE N ecrit_le D, N ecrit_par P, P nom 'jphc', D day > (today-10);
+ Note K WHERE K ecrit_le D, K ecrit_par Y, D day > (today-10), Y nom 'jphc';
+
+Forme canonique
+```````````````
+
+::
+
+ N = Variable('N')
+ D = Variable('D')
+ P = Variable('P')
+ canon1 = {
+ 'all_variables': [N, D, P],
+ 'selected' : [N],
+ 'restriction' : {'is' : [(N, 'Note')],
+ 'day': [(D, '> (today-10)')],
+ 'ecrit_le' : [(N, D)],
+ 'ecrit_par' : [(N, P)],
+ 'nom' : [(P, 'jphc')]
+ }
+ }
+ N.name = 'is_Note:ecrit_le:ecrit_par:1'
+ D.name = 'ecrit_le:day_> (today-10)'
+ P.name = 'ecrit_par:nom_jphc'
+ sort(canon1)
+
+
+ K = Variable('K')
+ D = Variable('D')
+ Y = Variable('Y')
+ canon2 = {
+ 'all_variables': [K, D, Y],
+ 'selected' : [K],
+ 'restriction' : {'is' : [(K, 'Note')],
+ 'day': [(D, '> (today-10)')],
+ 'ecrit_le' : [(K, D)],
+ 'ecrit_par' : [(K, Y)],
+ 'nom' : [(Y, 'jphc')]
+ }
+ }
+ K.name = 'is_Note:ecrit_le:ecrit_par:1'
+ D.name = 'ecrit_le:day_> (today-10)'
+ Y.name = 'ecrit_par:nom_jphc'
+ sort(canon2)
+
+ canon1 == canon2
+
+
+Exemple 3
+---------
+
+Formules équivalentes
+`````````````````````
+
+::
+
+ Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ludal';
+ Note K WHERE K ecrit_le D, K ecrit_par Y, D day > (today -10), Y nom in ('jphc', 'ludal');
+
+Forme canonique
+```````````````
+
+::
+
+ N = Variable('N')
+ D = Variable('D')
+ P = Variable('P')
+ canon1 = {
+ 'all_variables': [N, D, P],
+ 'selected' : [N],
+ 'restriction' : {'is' : [(N, 'Note')],
+ 'day': [(D, '> (today-10)')],
+ 'ecrit_le' : [(N, D)],
+ 'ecrit_par' : [(N, P)],
+ 'nom' : [(P, 'jphc'), (P, 'ludal')]
+ }
+ }
+ N.name = 'is_Note:ecrit_le:ecrit_par:1'
+ D.name = 'ecrit_le:day_> (today-10)'
+ P.name = 'ecrit_par:nom_jphc'
+ sort(canon1)
+
+
+ K = Variable('K')
+ D = Variable('D')
+ Y = Variable('Y')
+ canon2 = {
+ 'all_variables': [K, D, Y],
+ 'selected' : [K],
+ 'restriction' : {'is' : [(K, 'Note')],
+ 'day': [(D, '> (today-10)')],
+ 'ecrit_le' : [(K, D)],
+ 'ecrit_par' : [(K, Y)],
+ 'nom' : [(Y, 'jphc'), (Y, 'ludal')]
+ }
+ }
+ K.name = 'is_Note:ecrit_le:ecrit_par:1'
+ D.name = 'ecrit_le:day_> (today-10)'
+ Y.name = 'ecrit_par:nom_jphc'
+ sort(canon2)
+
+ canon1 == canon2
+
+
+
+Problèmes
+---------
+
+1. Les paires de formules suivantes sont considérées comme identiques par
+ l'algorithme ci-dessus alors qu'elles ne le sont pas:
+
+::
+
+ Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ludal';
+ Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc', P nom 'ludal';
+
+ Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P prenom 'ludal';
+ Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc', P prenom 'ludal';
+
+donne comme restriction:
+
+::
+
+ 'restriction' : {'is' : [(K, 'Note')],
+ 'day': [(D, '> (today-10)')],
+ 'ecrit_le' : [(K, D)],
+ 'ecrit_par' : [(K, Y)],
+ 'nom_nom' : [(Y, 'jphc', Y, 'ludal')]
+ }
+
+2. risque de collision dans les noms de variables non sélectionnées (un exemple ?).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/conf.py Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,194 @@
+# -*- coding: utf-8 -*-
+#
+# RQL documentation build configuration file, created by
+# sphinx-quickstart on Tue Nov 4 07:54:06 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default value; values that are commented out
+# serve to show the default value.
+# copyright 2004-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of rql.
+#
+# rql is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# rql is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with rql. If not, see <http://www.gnu.org/licenses/>.
+
+# If your extensions are in another directory, add it here. If the directory
+# is relative to the documentation root, use os.path.abspath to make it
+# absolute, like shown here.
+# sys.path.append(os.path.abspath('some/directory'))
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'RQL'
+copyright = '2008, Sylvain Thenault'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '0.20.2'
+# The full version, including alpha/beta/rc tags.
+release = '0.20.2'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+# today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+# unused_docs = []
+
+# List of directories, relative to source directories, that shouldn't be searched
+# for source files.
+# exclude_dirs = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'sphinx-default.css'
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+# html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+# html_short_title = None
+
+# The name of an image file (within the static path) to place at the top of
+# the sidebar.
+# html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['.static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+# html_additional_pages = {}
+
+# If false, no module index is generated.
+# html_use_modindex = True
+
+# If false, no index is generated.
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+# html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+# html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+# html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'RQLdoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+# latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+# latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [
+ ('index', 'RQL.tex', 'RQL Documentation',
+ 'Sylvain Thenault', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+# latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+# latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = []
+
+# If false, no module index is generated.
+# latex_use_modindex = True
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/index.txt Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,23 @@
+.. RQL documentation master file, created by sphinx-quickstart on Tue Nov 4 07:54:06 2008.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Documentation technique de RQL
+==============================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ specifications_fr.txt
+ canonisation.txt
+ tutoriel_fr.txt
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/rql_windows.txt Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,121 @@
+Compiling rql for Windows
+=========================
+
+
+:author: Alexandre Fayolle
+:date: 2009/09/09
+
+RQL can use either logilab.constraint or gecode to perform type
+inference. This document explains how the gecode support can be added
+for the Windows platform.
+
+The short way
+-------------
+
+Download and install http://ftp.logilab.org/pub/rql/rql-0.23.0.win32-py2.5.exe
+
+The long way
+------------
+
+Problem statement: we want to use python2.5 on windows. Compiling C
+extensions requires Visual Studio 2003, but Gecode requires Visual
+Studio 2008. So we are stuck with using MinGW, and then again Gecode
+requires gcc 4.2 or later and cygwin to support building.
+But cygwin doesn't come with a mingw enabled gcc 4.x (only 3.x
+available), so some stiching is required.
+
+Dependencies installation
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* cygwin_: download http://www.cygwin.com/setup.exe, run it and select the following
+ packages:
+
+ - diffutils
+ - perl
+ - g++-mingw
+ - some text editor of your choice (nano, vim...)
+
+* mingw_: download the following files:
+
+ - `gcc-g++-4.4.0-bin <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-bin.tar.gz/download>`_
+
+ - `gcc-g++-4.4.0-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-dll.tar.gz/download>`_
+
+ - `gcc-core-4.4.0-bin <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-bin.tar.gz/download>`_
+
+ - `gcc-core-4.4.0-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-dll.tar.gz/download>`_
+
+ - `gmp-4.2.4-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gmp-4.2.4-mingw32-dll.tar.gz/download>`_
+
+ - `mpfr-2.4.1-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/mpfr-2.4.1-mingw32-dll.tar.gz/download>`_
+
+ - `binutils-2.19.1-bin <http://sourceforge.net/projects/mingw/files/GNU%20Binutils/Current%20Release_%20GNU%20binutils-2.19.1/binutils-2.19.1-mingw32-bin.tar.gz/download>`_
+
+ - `w32api-3.13-dev <http://sourceforge.net/projects/mingw/files/MinGW%20API%20for%20MS-Windows/Current%20Release_%20w32api-3.13/w32api-3.13-mingw32-dev.tar.gz/download>`_
+
+ - `mingwrt-3.15.2-dev <http://sourceforge.net/projects/mingw/files/MinGW%20Runtime/mingwrt-3.15.2/mingwrt-3.15.2-mingw32-dev.tar.gz/download>`_
+
+
+Create ``c:\MinGW``. Launch a cygwin shell, go to ``/cygdrive/c/MinGW`` and
+untar all the mingw tarballs
+
+Edit ``/etc/profile`` and go to the place where the ``PATH`` environment
+variable is set. Change the line to *prepend*
+``/cygdrive/c/MinGW/bin:/cygdrive/c/MinGW/libexec/mingw32/4.4.0`` to the ``PATH``
+
+* download and untar `Gecode 3.1.0 source distribution <http://www.gecode.org/download/gecode-3.1.0.tar.gz>`_.
+
+
+Compiling gecode
+~~~~~~~~~~~~~~~~
+
+In a cygwin shell, go the the untarred Gecode source directory and run::
+
+ $ ./configure --enable-version-specific-runtime-libs \
+ --disable-shared --disable-qt --disable-gist \
+ --disable-examples --enable-static
+
+Edit gecode/support/config.hpp, and change the line ::
+
+ #define GECODE_USE_GETTIMEOFDAY 1
+
+to::
+
+ #define GECODE_USE_CLOCK 1
+
+run::
+
+ $ make CXXFLAGS="-I. -O1 -DNDEBUG -Wextra -Wall -pipe -ggdb \
+ -fno-strict-aliasing -ffast-math -mthreads -DGECODE_BUILD_SUPPORT -static-libgcc"
+
+While this runs, consider renting some Bollywood movie (I enjoyed `this one
+<http://www.imdb.com/title/tt0172684/>`_) and watching it.
+
+
+Compiling the C extension in rql
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+in a Windows shell (aka "DOS Console"), go the the rql directory and
+run::
+
+ $ set PATH=%PATH%;c:\MinGW\bin;c:\MinGW\libexec\mingw32\4.4.0
+ $ python setup.py build_ext -c mingw32 \
+ -Ic:\temp\gecode-3.1.0 \
+ -Lc:\temp\gecode-3.1.0
+ --in-place
+
+Test
+~~~~
+
+Open a new console (to get the default ``PATH``). Go to the parent
+directory of rql. Launch the Python interpreter, and type::
+
+ >>> import rql.analyze
+
+If this works, congratulation, you're done.
+
+
+
+.. _cygwin: http://www.cygwin.com
+.. _mingw: http://www.mingw.org
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/specifications_en.txt Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,588 @@
+.. -*- coding: utf-8 -*-
+
+
+===================================================
+Specification "Relations Query Language" (Hercules)
+===================================================
+
+Introduction
+============
+
+Goals RQL
+---------
+
+The goal is to have a language emphasizing the way of browsing
+relations. As such, attributes will be regarded as cases of
+special relations (in terms of implementation, the user
+language not to see virtually no difference between an attribute and a
+relation).
+
+RQL is inspired by SQL but is the highest level. A knowledge of the
+`CubicWeb` schema defining the application is necessary.
+
+Comparison with existing languages
+----------------------------------
+
+SQL
+```
+RQL builds on the features of SQL but is at a higher level
+(the current implementation of RQL generates SQL). For that it is limited
+to the way of browsing relations and introduces variables.
+The user does not need to know the model underlying SQL, but the `CubicWeb`
+scheam defining the application.
+
+Versa
+`````
+Should I look in more detail, but here is already some ideas for
+the moment ... Versa_ is the language most similar to what we wanted
+to do, but the model underlying data being RDF, there is some
+number of things such as namespaces or handling of the RDF types which
+does not interest us. On the functionality level, Versa_ is very comprehensive
+including through many functions of conversion and basic types manipulation,
+which may need to be guided at one time or another.
+Finally, the syntax is a little esoteric.
+
+See also
+``````````
+RDFQL_
+
+
+The different types of queries
+------------------------------
+
+Search ( `Any`)
+ This type of query can extract entities and attributes of entities.
+
+Inserting entities ( `INSERT`)
+ This type of query is used to insert new entities in the database. It
+ will also create direct relationships entities newly created.
+
+Update entities, relations creation( `SET`)
+ This type of query updates existing entities in the database,
+ or create relations between existing entities.
+
+Deletion of entities or relationship ( `DELETE`)
+ This type of query allows for the removal of entities and relations existing
+ in the database.
+
+
+
+Examples
+========
+
+(see the tutorial: ref: `tutorielRQL` for more examples)
+
+Search Query
+------------
+
+ [ `DISTINCT`] <entity type> V1 (V2) \ *
+ [ `GROUPBY` V1 (V2) \*] [ `ORDERBY` <orderterms>]
+ [ `WHERE` <restriction>]
+ [ `LIMIT` <value>] [ `OFFSET` <value>]
+
+:entity type:
+ Type of selected variables.
+ The special type `Any` is equivalent to not specify a type.
+:restriction:
+ list of relations to go through whic follow the pattern
+ `V1 relation V2 | <static value>`
+:orderterms:
+ Definition of the selection order: variable or column number followed by
+ sorting method ( `ASC`, `DESC`), ASC is the default.
+:note for grouped queries:
+ For grouped queries (e.g., a clause `GROUPBY`), all
+ selected variables must be aggregated or grouped.
+
+
+
+- *Search for the object of identifier 53*
+ ::
+
+ Any WHERE X
+ X eid 53
+
+- *Search material such as comics, owned by syt and available*
+ ::
+
+ WHERE X Document
+ X occurence_of F, F class C, C name 'Comics'
+ X owned_by U, U login 'syt'
+ X available true
+
+- *Looking for people working for eurocopter interested in training*
+ ::
+
+ Person P WHERE
+ P work_for P, S name 'Eurocopter'
+ P interested_by T, T name 'training'
+
+- *Search note less than 10 days old written by jphc or ocy*
+ ::
+
+ Note N WHERE
+ N written_on D, D day> (today -10),
+ N written_by P, P name 'jphc' or P name 'ocy'
+
+- *Looking for people interested in training or living in Paris*
+ ::
+
+ Person P WHERE
+ (P interested_by T, T name 'training') or
+ (P city 'Paris')
+
+- *The name and surname of all people*
+ ::
+
+ Any N, P WHERE
+ X is Person, X name N, X first_name P
+
+ Note that the selection of several entities generally force
+ the use of "Any" because the type specification applies otherwise
+ to all the selected variables. We could write here
+ ::
+
+ String N, P WHERE
+ X is Person, X name N, X first_name P
+
+
+Insertion query
+---------------
+
+ `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments>
+ [ `WHERE` <restriction>]
+
+: assignments:
+ list of relations to assign in the form `V1 relationship V2 | <static value>`
+
+The restriction can define variables used in assignments.
+
+Caution, if a restriction is specified, the insertion is done for
+*each line results returned by the restriction*.
+
+- *Insert a new person named 'foo'*
+ ::
+
+ INSERT Person X: X name 'widget'
+
+- *Insert a new person named 'foo', another called 'nice' and a 'friend' relation
+ between them*
+ ::
+
+ INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y
+
+- *Insert a new person named 'foo' and a 'friend' relation with an existing
+ person called 'nice'*
+ ::
+
+ INSERT Person X: X name 'foo', X friend Y WHERE name 'nice'
+
+Update and relation creation queries
+------------------------------------
+ `SET` <assignements>
+ [ `WHERE` <restriction>]
+
+Caution, if a restriction is specified, the update is done *for
+each line results returned by the restriction*.
+
+- *Renaming of the person named 'foo' to 'bar' with the first name changed*
+ ::
+
+ SET X name 'bar', X first_name 'original' where X is Person X name 'foo'
+
+- *Insert a relation of type 'know' between objects linked by
+ the relation of type 'friend'*
+ ::
+
+ SET X know Y WHERE X friend Y
+
+
+Deletion query
+--------------
+ `DELETE` (<entity type> V) | (V1 relation v2 ),...
+ [ `WHERE` <restriction>]
+
+Caution, if a restriction is specified, the deletion is made *for
+each line results returned by the restriction*.
+
+- *Deletion of the person named 'foo'*
+ ::
+
+ DELETE Person X WHERE X name 'foo'
+
+- *Removal of all relations of type 'friend' from the person named 'foo'*
+ ::
+
+ DELETE X friend Y WHERE X is Person, X name 'foo'
+
+
+
+Language definition
+===================
+
+Reserved keywords
+-----------------
+The keywords are not case sensitive.
+
+::
+
+ DISTINCT, INSERT, SET, DELETE,
+ WHERE, AND, OR, NOT
+ IN, LIKE, ILIKE,
+ TRUE, FALSE, NULL, TODAY, NOW
+ GROUPBY, ORDERBY, ASC, DESC
+
+
+Variables and Typing
+--------------------
+
+With RQL, we do not distinguish between entities and attributes. The
+value of an attribute is considered an entity of a particular type (see
+below), linked to one (real) entity by a relation called the name of
+the attribute.
+
+Entities and values to browse and/or select are represented in
+the query by *variables* that must be written in capital letters.
+
+There is a special type **Any**, referring to a non specific type.
+
+We can restrict the possible types for a variable using the
+special relation **is**.
+The possible type(s) for each variable is derived from the schema
+according to the constraints expressed above and thanks to the relations between
+each variable.
+
+Built-in types
+``````````````
+
+The base types supported are string (between double or single quotes),
+integers or floats (the separator is the'.'), dates and
+boolean. We expect to receive a schema in which types String,
+Int, Float, Date and Boolean are defined.
+
+* `String` (literal: between double or single quotes).
+* `Int`, `Float` (separator being'.').
+* `Date`, `Datetime`, `Time` (literal: string YYYY/MM/DD [hh:mm] or keywords
+ `TODAY` and `NOW`).
+* `Boolean` (keywords `TRUE` and `FALSE`).
+* `Keyword` NULL.
+
+
+Operators
+---------
+
+Logical Operators
+```````````````````
+::
+
+ AND, OR, ','
+
+',' is equivalent to 'AND' but with the smallest among the priority
+of logical operators (see :ref:`PriorityOperators`).
+
+Mathematical Operators
+``````````````````````
+::
+
+ +, -, *, /
+
+Comparison operators
+````````````````````
+::
+
+ =, <, <=, >=, > = ~, IN, LIKE, ILIKE
+
+* The operator `=` is the default operator.
+
+* The operator `LIKE` equivalent to `~=` can be used with the
+ special character `%` in a string to indicate that the chain
+ must start or finish by a prefix/suffix:
+ ::
+
+ Any X WHERE X name =~ 'Th%'
+ Any X WHERE X name LIKE '%lt'
+
+* The operator `ILIKE` is a case-insensitive version of `LIKE`.
+
+* The operator `IN` provides a list of possible values:
+ ::
+
+ Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault')
+
+
+XXX nico: A trick <> 'bar' would not it be more convenient than NOT A
+trick 'bar'?
+
+.. _PriorityOperators:
+
+Operators priority
+``````````````````
+
+1. '*', '/'
+
+2. '+', '-'
+
+3. 'and'
+
+4. 'or'
+
+5. ','
+
+
+Advanced Features
+-----------------
+
+Functions aggregates
+````````````````````
+::
+
+ COUNT, MIN, MAX, AVG, SUM
+
+Functions on string
+```````````````````
+::
+
+ UPPER, LOWER
+
+Optional relations
+``````````````````
+
+* They allow you to select entities related or not to another.
+
+* You must use the `?` behind the variable to specify that the relation
+ toward it is optional:
+
+ - Anomalies of a project attached or not to a version ::
+
+ Any X, V WHERE X concerns P, P eid 42, X corrected_in V?
+
+ - All cards and the project they document if necessary ::
+
+ Any C, P WHERE C is Card, P? documented_by C
+
+
+
+BNF grammar
+-----------
+
+The terminal elements are in capital letters, non-terminal in lowercase.
+The value of the terminal elements (between quotes) is a Python regular
+expression.
+::
+
+ statement:: = (select | delete | insert | update) ';'
+
+
+ # select specific rules
+ select ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
+
+ selected_terms ::= expression ( ',' expression)*
+
+ group ::= 'GROUPBY' VARIABLE ( ',' VARIABLE)*
+
+ sort ::= 'ORDERBY' sort_term ( ',' sort_term)*
+
+ sort_term ::= VARIABLE sort_method =?
+
+ sort_method ::= 'ASC' | 'DESC'
+
+
+ # delete specific rules
+ delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
+
+
+ # insert specific rules
+ insert ::= 'INSERT' variables_declaration ( ':' relations_declaration)? restriction?
+
+
+ # update specific rules
+ update ::= 'SET' relations_declaration restriction
+
+
+ # common rules
+ variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
+
+ relations_declaration ::= simple_relation (',' simple_relation)*
+
+ simple_relation ::= VARIABLE R_TYPE expression
+
+ restriction ::= 'WHERE' relations
+
+ relations ::= relation (LOGIC_OP relation)*
+ | '(' relations')'
+
+ relation ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
+ | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')'
+
+ expression ::= var_or_func_or_const (MATH_OP var_or_func_or_const) *
+ | '(' expression ')'
+
+ var_or_func_or_const ::= VARIABLE | function | constant
+
+ function ::= FUNCTION '(' expression ( ',' expression) * ')'
+
+ constant ::= KEYWORD | STRING | FLOAT | INT
+
+ # tokens
+ LOGIC_OP ::= ',' | 'GOLD' | 'AND'
+ MATH_OP ::= '+' | '-' | '/' | '*'
+ COMP_OP ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE' | 'ILIKE'
+
+ FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'upper' | 'LOWER'
+
+ VARIABLE ::= '[A-Z][A-Z0-9]*'
+ E_TYPE ::= '[A-Z]\w*'
+ R_TYPE ::= '[a-z_]+'
+
+ KEYWORD ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
+ STRING ::= "'([^'\]|\\.)*'" |'"([^\"]|\\.)*\"'
+ FLOAT ::= '\d+\.\d*'
+ INT ::= '\d+'
+
+
+Remarks
+-------
+
+Sorting and groups
+``````````````````
+
+- For grouped queries (e.g. with a GROUPBY clause), all
+ selected variables should be grouped.
+
+- To group and/or sort by attributes, we can do: "X,L user U, U
+ login L GROUPBY L, X ORDERBY L"
+
+- If the sorting method (SORT_METHOD) is not specified, then the sorting is
+ ascendant.
+
+Negation
+````````
+
+* A query such as `Document X WHERE NOT X owned_by U` means "the
+ documents have no relation `owned_by`".
+* But the query `Document X WHERE NOT X owned_by U, U login "syt"`
+ means "the documents have no relation `owned_by` with the user
+ syt". They may have a relation "owned_by" with another user.
+
+Identity
+````````
+
+You can use the special relation `identity` in a query to
+add an identity constraint between two variables. This is equivalent
+to ``is`` in python::
+
+ Any A WHERE A comments B, A identity B
+
+return all objects that comment themselves. The relation
+`identity` is especially useful when defining the rules for securities
+with `RQLExpressions`.
+
+Implementation
+==============
+
+Internal representation (syntactic tree)
+----------------------------------------
+
+The tree research does not contain the selected variables
+(e.g. there is only what follows "WHERE").
+
+The insertion tree does not contain the variables inserted or relations
+defined on these variables (e.g. there is only what follows "WHERE").
+
+The removal tree does not contain the deleted variables and relations
+(e.g. there is only what follows the "WHERE").
+
+The update tree does not contain the variables and relations updated
+(e.g. there is only what follows the "WHERE").
+
+::
+
+ Select ((Relationship | And | Gold)?, Group?, Sort?)
+ Insert (Relations | And | Gold)?
+ Delete (Relationship | And | Gold)?
+ Update (Relations | And | Gold)?
+
+ And ((Relationship | And | Gold), (Relationship | And | Gold))
+ Or ((Relationship | And | Gold), (Relationship | And | Gold))
+
+ Relationship ((VariableRef, Comparison))
+
+ Comparison ((Function | MathExpression | Keyword | Constant | VariableRef) +)
+
+ Function (())
+ MathExpression ((MathExpression | Keyword | Constant | VariableRef), (MathExpression | Keyword | Constant | VariableRef))
+
+ Group (VariableRef +)
+ Sort (SortTerm +)
+ SortTerm (VariableRef +)
+
+ VariableRef ()
+ Variable ()
+ Keyword ()
+ Constant ()
+
+
+Remarks
+-------
+
+- The current implementation does not support linking two relations of type
+ 'is' with a OR. I do not think that the negation is supported on this type
+ of relation (XXX FIXME to be confirmed).
+
+- Relations defining the variables must be left to those using them.
+ For example::
+
+ Point P where P abs X, P ord Y, P value X+Y
+
+ is valid, but::
+
+ Point P where P abs X, P value X+Y, P ord Y
+
+ is not.
+
+
+
+Conclusion
+==========
+
+Limitations
+-----------
+
+It lacks at the moment:
+
+- COALESCE
+
+- restrictions on groups (HAVING)
+
+and certainly other things ...
+
+A disadvantage is that to use this language we must know the
+format used (with real relation names and entities, not those viewing
+in the user interface). On the other hand, we can not really bypass
+that, and it is the job of a user interface to hide the RQL.
+
+
+Topics
+------
+
+It would be convenient to express the schema matching
+relations (non-recursive rules)::
+
+ Document class Type <-> Document occurence_of Fiche class Type
+ Sheet class Type <-> Form collection Collection class Type
+
+Therefore 1. becomes::
+
+ Document X where
+ X class C, C name 'Cartoon'
+ X owned_by U, U login 'syt'
+ X available true
+
+I'm not sure that we should handle this at RQL level ...
+
+There should also be a special relation 'anonymous'.
+
+
+
+.. _Versa: Http://uche.ogbuji.net/tech/rdf/versa/
+.. _RDFQL: Http://www.w3.org/TandS/QL/QL98/pp/rdfquery.html
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/specifications_fr.txt Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,588 @@
+.. -*- coding: utf-8 -*-
+
+=================================================
+Spécification "Relation Query Language" (Hercule)
+=================================================
+
+:Author: Sylvain Thénault
+:Organization: Logilab
+:Version: $Revision: 1.10 $
+:Date: $Date: 2004-05-18 15:04:13 $
+
+Introduction
+============
+
+Objectifs de RQL
+----------------
+
+L'objectif est d'avoir un langage mettant l'accent sur le parcours de
+relations. A ce titre les attributs seront donc considérés comme des cas
+particuliers de relations (au niveau de l'implémentation, l'utilisateur du
+langage ne devant quasiment pas voir de différence entre un attribut et une
+relation).
+
+RQL s'inspire de SQL mais se veut plus haut niveau. Une connaissance du schéma
+Cubicweb définissant l'application est nécessaire.
+
+
+Comparaison avec des langages existants
+---------------------------------------
+
+SQL
+```
+RQL s'inspire des fonctionnalités de SQL mais se veut à un plus haut niveau
+(l'implémentation actuelle de RQL génère du SQL). Pour cela il se limite au
+parcours de relations et introduit des variables. L'utilisateur n'a pas besoin
+de connaitre le modèle SQL sous-jacent, mais uniquement le schéma Erudi
+définissant l'application.
+
+Versa
+`````
+Faudrait que je regarde plus en détail, mais voilâ déja quelques idées pour
+l'instant... Versa_ est le langage ressemblant le plus à ce que nous voulions
+faire, mais le modèle de donnée sous-jacent étant du RDF, il y a un certain
+nombre de choses tels que les namespaces ou la manipulation des types RDF qui
+ne nous intéressent pas. Niveau fonctionnalité, Versa_ est très complet
+notamment grâce à de nombreuses fonctions de conversion et de manipulations
+des types de base, dont il faudra peut-être s'inspirer à un moment ou à
+l'autre. Enfin, La syntaxe est un peu ésotérique.
+
+Voir aussi
+``````````
+RDFQL_
+
+
+Les différents types de requêtes
+--------------------------------
+
+Recherche (`Any`)
+ Ce type de requête permet d'extraire des entités ou des attributs d'entités.
+
+Insertion d'entités (`INSERT`)
+ Ce type de requête permet d'insérer de nouvelles entités dans la base. On
+ permettra également la création directe de relations sur les entités
+ nouvellement créées.
+
+Mise à jour d'entités, création de relations (`SET`)
+ Ce type de requête permet de mettre à jours des entités existantes dans la base,
+ ou de créer des relations entres des entités existantes.
+
+Suppression d'entités ou de relation (`DELETE`)
+ Ce type de requête permet de supprimer des entités et relations existantes dans
+ la base.
+
+
+
+Exemples
+========
+
+(voir le tutoriel :ref:`tutorielRQL` pour plus d'exemples)
+
+Requête de recherche
+--------------------
+
+ [`DISTINCT`] <type d'entité> V1(, V2)\*
+ [`GROUPBY` V1(, V2)\*] [`ORDERBY` <orderterms>]
+ [`WHERE` <restriction>]
+ [`LIMIT` <value>] [`OFFSET` <value>]
+
+:type d'entité:
+ Type de la ou des variables séléctionnées.
+ Le type spécial `Any`, revient à ne pas spécifier de type.
+:restriction:
+ liste des relations à parcourir sous la forme
+ `V1 relation V2|<valeur constante>`
+:orderterms:
+ Définition de l'ordre de selection : variable ou n° de colonne suivie de la
+ méthode de tri (`ASC`, `DESC`), ASC étant la valeur par défaut.
+:note pour les requêtes groupées:
+ Pour les requêtes groupées (i.e. avec une clause `GROUPBY`), toutes les
+ variables sélectionnée doivent être soit groupée soit aggrégée.
+
+
+
+- *recherche de l'objet ayant l'identifiant 53*
+ ::
+
+ Any X WHERE
+ X eid 53
+
+- *recherche des documents de type bande dessinée, appartenant à syt et disponible*
+ ::
+
+ Document X WHERE
+ X occurence_of F, F class C, C name 'Bande dessinée',
+ X owned_by U, U login 'syt',
+ X available true
+
+- *recherche des personnes travaillant pour eurocopter intéressé par la formation*
+ ::
+
+ Personne P WHERE
+ P travaille_pour S, S nom 'Eurocopter',
+ P interesse_par T, T nom 'formation'
+
+- *recherche des notes de moins de 10 jours écrites par jphc ou ocy*
+ ::
+
+ Note N WHERE
+ N ecrit_le D, D day > (today -10),
+ N ecrit_par P, P nom 'jphc' or P nom 'ocy'
+
+- *recherche des personnes intéressées par la formation ou habitant à Paris*
+ ::
+
+ Personne P WHERE
+ (P interesse_par T, T nom 'formation') or
+ (P ville 'Paris')
+
+- *Le nom et le prénom de toutes les personnes*
+ ::
+
+ Any N, P WHERE
+ X is Personne, X nom N, X prenom P
+
+ On remarquera que la selection de plusieurs entités force généralement
+ l'utilisation de "Any", car la spécification de type s'applique sinon
+ à toutes les variables séléctionnées. On aurait pu écrire ici
+ ::
+
+ String N, P WHERE
+ X is Personne, X nom N, X prenom P
+
+
+Requête d'insertion
+-------------------
+ `INSERT` <type d'entité> V1(, <type d'entité> V2)\* `:` <assignements>
+ [`WHERE` <restriction>]
+
+:assignements:
+ liste des relations à assigner sous la forme `V1 relation V2|<valeur constante>`
+
+La restriction permet de définir des variables utilisées dans les assignements.
+
+Attention, si une restriction est spécifiée, l'insertion est effectuée *pour
+chaque ligne de résultat renvoyée par la restriction*.
+
+- *insertion d'une nouvelle personne nommée 'bidule'*
+ ::
+
+ INSERT Personne X: X nom 'bidule'
+
+- *insertion d'une nouvelle personne nommée 'bidule', d'une autre nommée 'chouette' et d'une relation 'ami' entre eux*
+ ::
+
+ INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'chouette', X ami Y
+
+- *insertion d'une nouvelle personne nommée 'bidule' et d'une relation 'ami' avec une personne existante nommée 'chouette'*
+ ::
+
+ INSERT Personne X: X nom 'bidule', X ami Y WHERE Y nom 'chouette'
+
+
+Requête de mise à jour, création de relations
+---------------------------------------------
+ `SET` <assignements>
+ [`WHERE` <restriction>]
+
+Attention, si une restriction est spécifiée, la mise à jour est effectuée *pour
+chaque ligne de résultat renvoyée par la restriction*.
+
+- *renommage de la personne nommée 'bidule' en 'toto', avec modification du prénom*
+ ::
+
+ SET X nom 'toto', X prenom 'original' WHERE X is Person, X nom 'bidule'
+
+- *insertion d'une relation de type 'connait' entre les objets reliés par la relation de type 'ami'*
+ ::
+
+ SET X know Y WHERE X ami Y
+
+
+Requête de suppression
+----------------------
+ `DELETE` (<type d''entité> V) | (V1 relation v2),...
+ [`WHERE` <restriction>]
+
+Attention, si une restriction est spécifiée, la suppression est effectuée *pour
+chaque ligne de résultat renvoyée par la restriction*.
+
+- *supression de la personne nommé 'toto'*
+ ::
+
+ DELETE Person X WHERE X nom 'toto'
+
+- *suppression de toutes les relations de type 'ami' partant de la personne nommée 'toto'*
+ ::
+
+ DELETE X ami Y WHERE X is Person, X nom 'toto'
+
+
+
+Définition du langage
+=====================
+
+Mots clés réservés
+------------------
+Les mots clés ne sont pas sensibles à la casse.
+
+::
+
+ DISTINCT, INSERT, SET, DELETE,
+ WHERE, AND, OR, NOT
+ IN, LIKE, ILIKE,
+ TRUE, FALSE, NULL, TODAY, NOW
+ GROUPBY, ORDERBY, ASC, DESC
+
+
+Variables et Typage
+-------------------
+
+Au niveau de RQL, on ne fait pas de distinction entre entités et attributs. La
+valeur d'un attribut est considérée comme une entité d'un type particulier (voir
+ci-dessous), lié à une (vraie) entité par une relation du nom de l'attribut.
+
+Les entités et valeurs à parcourir et / ou séléctionner sont représentées dans
+la requête par des *variables* qui doivent être écrites en majuscule.
+
+Il existe un type spécial **Any**, revenant à ne pas spécifier de type.
+
+On peut contraindre les types possibles pour une variable à l'aide de la
+relation spéciale **is**.
+
+Le(s) type(s) possible(s) pour chaque variable est déduit du schema en
+fonction des contraintes exprimées ci-dessus et à l'aide des relations entre
+chaque variable.
+
+Types de bases
+``````````````
+
+Les types de bases supportés sont les chaines (entre doubles ou simples quotes),
+les nombres entiers ou flottant (le séparateur étant le '.'), les dates et les
+booléens. On s'attend donc à recevoir un schéma dans lequel les types String,
+Int, Float, Date et Boolean sont définis.
+
+* `String` (litéral: entre doubles ou simples quotes).
+* `Int`, `Float` (le séparateur étant le '.').
+* `Date`, `Datetime`, `Time` (litéral: chaîne YYYY/MM/DD[ hh:mm] ou mots-clés
+ `TODAY` et `NOW`).
+* `Boolean` (mots-clés `TRUE` et `FALSE`).
+* mot-clé `NULL`.
+
+
+Opérateurs
+----------
+
+Opérateurs logiques
+```````````````````
+::
+
+ AND, OR, ','
+
+"," est équivalent à "AND" mais avec la plus petite priorité parmi les
+opérateurs logiques (voir `Priorité des opérateurs`_).
+
+Opérateurs mathématiques
+````````````````````````
+::
+
+ +, -, *, /
+
+Opérateurs de comparaison
+`````````````````````````
+::
+
+ =, <, <=, >=, >, ~=, IN, LIKE, ILIKE
+
+* L'opérateur `=` est l'opérateur par défaut.
+
+* L'opérateur `LIKE` équivalent à `~=` permet d'utiliser le caractère `%` dans
+ une chaine de caractère pour indiquer que la chaîne doit commencer ou terminer
+ par un préfix/suffixe::
+
+ Any X WHERE X nom ~= 'Th%'
+ Any X WHERE X nom LIKE '%lt'
+
+* L'opérateur `ILIKE` est une version de `LIKE` qui n'est pas sensible à la
+ casse.
+
+* L'opérateur `IN` permet de donner une liste de valeurs possibles::
+
+ Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
+
+
+XXX nico: A truc <> 'titi' ne serait-il pas plus pratique que NOT A
+truc 'titi' ?
+
+Priorité des opérateurs
+```````````````````````
+
+1. '*', '/'
+
+2. '+', '-'
+
+3. 'and'
+
+4. 'or'
+
+5. ','
+
+
+Fonctionnalités avancées
+------------------------
+
+Fonctions d'aggrégat
+````````````````````
+::
+
+ COUNT, MIN, MAX, AVG, SUM
+
+Fonctions sur les chaines
+`````````````````````````
+::
+
+ UPPER, LOWER
+
+Relations optionnelles
+``````````````````````
+
+* Elles permettent de sélectionner des entités liées ou non à une autre.
+
+* Il faut utiliser le `?` derrière la variable pour spécifier que la relation
+ vers celle-ci est optionnelle :
+
+ - Anomalies d'un projet attachées ou non à une version ::
+
+ Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
+
+ - Toutes les fiches et le projet qu'elles documentent le cas échéant ::
+
+ Any C,P WHERE C is Card, P? documented_by C
+
+
+
+Grammaire BNF
+-------------
+Les éléments terminaux sont en majuscules, les non-terminaux en minuscule. La
+valeur des éléments terminaux (entre quotes) correspond à une expression
+régulière Python.
+::
+
+ statement ::= (select | delete | insert | update) ';'
+
+
+ # select specific rules
+ select ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
+
+ selected_terms ::= expression (',' expression)*
+
+ group ::= 'GROUPBY' VARIABLE (',' VARIABLE)*
+
+ sort ::= 'ORDERBY' sort_term (',' sort_term)*
+
+ sort_term ::= VARIABLE sort_method?
+
+ sort_method ::= 'ASC' | 'DESC'
+
+
+ # delete specific rules
+ delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
+
+
+ # insert specific rules
+ insert ::= 'INSERT' variables_declaration (':' relations_declaration)? restriction?
+
+
+ # update specific rules
+ update ::= 'SET' relations_declaration restriction
+
+
+ # common rules
+ variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
+
+ relations_declaration ::= simple_relation (',' simple_relation)*
+
+ simple_relation ::= VARIABLE R_TYPE expression
+
+ restriction ::= 'WHERE' relations
+
+ relations ::= relation (LOGIC_OP relation)*
+ | '(' relations ')'
+
+ relation ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
+ | 'NOT'? VARIABLE R_TYPE 'IN' '(' expression (',' expression)* ')'
+
+ expression ::= var_or_func_or_const (MATH_OP var_or_func_or_const)*
+ | '(' expression ')'
+
+ var_or_func_or_const ::= VARIABLE | function | constant
+
+ function ::= FUNCTION '(' expression (',' expression)* ')'
+
+ constant ::= KEYWORD | STRING | FLOAT | INT
+
+ # tokens
+ LOGIC_OP ::= ',' | 'OR' | 'AND'
+ MATH_OP ::= '+' | '-' | '/' | '*'
+ COMP_OP ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE'
+
+ FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER'
+
+ VARIABLE ::= '[A-Z][A-Z0-9]*'
+ E_TYPE ::= '[A-Z]\w*'
+ R_TYPE ::= '[a-z_]+'
+
+ KEYWORD ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
+ STRING ::= "'([^'\]|\\.)*'" | '"([^\"]|\\.)*\"'
+ FLOAT ::= '\d+\.\d*'
+ INT ::= '\d+'
+
+
+Remarques
+---------
+
+Tri et groupes
+``````````````
+
+- pour les requêtes groupées (i.e. avec une clause GROUPBY), toutes les
+ variables sélectionnées doivent être groupées
+
+- pour grouper ou/et trier sur les attributs on peut faire : "X,L user U, U
+ login L GROUPBY L,X ORDERBY L"
+
+- si la méthode de tri (SORT_METHOD) n'est pas précisée, alors le tri est
+ ascendant.
+
+Négation
+````````
+
+* Une requête du type `Document X WHERE NOT X owned_by U` revient à dire "les
+ documents n'ayant pas de relation `owned_by`".
+* En revanche la requête `Document X WHERE NOT X owned_by U, U login "syt"`
+ revient à dire "les documents n'ayant pas de relation `owned_by` avec
+ l'utilisateur syt". Ils peuvent avoir une relation "owned_by" avec un autre
+ utilisateur.
+
+Identité
+````````
+
+On peut utiliser la relation spéciale `identity` dans une requête pour
+rajouter une contrainte d'identité entre deux variables. C'est l'équivalent
+du ``is`` en python::
+
+ Any A WHERE A comments B, A identity B
+
+retournerait l'ensemble des objets qui se commentent eux-mêmes. La relation
+`identity` est surtout pratique lors de la définition des règles de sécurités
+avec des `RQLExpressions`.
+
+Implémentation
+==============
+
+Représentation interne (arbre syntaxique)
+-----------------------------------------
+
+L'arbre de recherche ne contient pas les variables sélectionnées (i.e. on n'y
+trouve que ce qui suit le "WHERE").
+
+L'arbre d'insertion ne contient pas les variables insérées ni les relations
+définies sur ces variables (i.e. on n'y trouve que ce qui suit le
+"WHERE").
+
+L'arbre de suppression ne contient pas les variables ou relations supprimées
+(i.e. on n'y trouve que ce qui suit le "WHERE").
+
+L'arbre de mise à jour ne contient pas les variables ou relations mises à jour
+(i.e. on n'y trouve que ce qui suit le "WHERE").
+
+::
+
+ Select ((Relation|And|Or)?, Group?, Sort?)
+ Insert (Relation|And|Or)?
+ Delete (Relation|And|Or)?
+ Update (Relation|And|Or)?
+
+ And ((Relation|And|Or), (Relation|And|Or))
+ Or ((Relation|And|Or), (Relation|And|Or))
+
+ Relation ((VariableRef, Comparison))
+
+ Comparison ((Function|MathExpression|Keyword|Constant|VariableRef)+)
+
+ Function (())
+ MathExpression ((MathExpression|Keyword|Constant|VariableRef), (MathExpression|Keyword|Constant|VariableRef))
+
+ Group (VariableRef+)
+ Sort (SortTerm+)
+ SortTerm (VariableRef+)
+
+ VariableRef ()
+ Variable ()
+ Keyword ()
+ Constant ()
+
+
+Remarques
+---------
+
+- l'implémentation actuelle ne supporte pas de lier deux relations ayant comme
+ type de relation 'is' avec un OR. Je ne pense pas que la négation ne
+ soit supportée non plus sur ce type de relation (à confirmer).
+
+- les relations définissant les variables doivent être à gauche de celles les
+ utilisant. Par exemple ::
+
+ Point P where P abs X, P ord Y, P value X+Y
+
+ est valide, mais ::
+
+ Point P where P abs X, P value X+Y, P ord Y
+
+ ne l'est pas.
+
+
+
+Conclusion
+==========
+
+Limitations
+-----------
+
+Il manque pour l'instant:
+
+- COALESCE
+
+- restriction sur les groupes (HAVING)
+
+et certainement d'autres choses...
+
+Un inconvénient est que pour utiliser ce langage il faut bien connaitre le
+schéma utilisé (avec les vrais noms de relations et d'entités, pas ceux affichés
+dans l'interface utilisateur). D'un autre coté, on peut pas vraiment contourner
+cela, et c'est le boulot d'une interface utilisateur de cacher le RQL.
+
+
+Sujets de réflexion
+-------------------
+
+Il serait pratique de pouvoir exprimer dans le schema des correspondances de
+relations (règles non récursives)::
+
+ Document class Type <-> Document occurence_of Fiche class Type
+ Fiche class Type <-> Fiche collection Collection class Type
+
+Ainsi 1. devient::
+
+ Document X where
+ X class C, C name 'Bande dessinée',
+ X owned_by U, U login 'syt',
+ X available true
+
+Je ne suis cependant pas sûr qu'il faille gérer ça au niveau de RQL...
+
+Il faudrait aussi une relation spéciale 'anonyme'.
+
+
+
+.. _Versa: http://uche.ogbuji.net/tech/rdf/versa/
+.. _RDFQL: http://www.w3.org/TandS/QL/QL98/pp/rdfquery.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/tutorial_en.txt Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,239 @@
+.. -*- coding: utf-8 -*-
+
+.. _tutorielRQL:
+
+==================================
+"Relation Query Language" tutorial
+==================================
+
+
+Let's discover RQL with examples.
+
+
+Schema
+------
+
+We will assume the following data model.
+
+:Person:
+
+::
+
+ name varchar(64) NOT NULL
+ firstname varchar(64)
+ sex char(1) DEFAULT 'M'
+ title varchar(128)
+ email varchar(128)
+ web varchar(128)
+ tel integer
+ birthdate date
+
+
+:Company:
+
+::
+
+ name varchar(64)
+ web varchar(128)
+ tel varchar(15)
+ adr varchar(128)
+ cp varchar(12)
+ city varchar(32)
+
+
+:Workcase:
+
+::
+
+ title varchar(128)
+ ref varchar(12)
+
+
+:Comment:
+
+::
+
+ diem date
+ type char(1)
+ para varchar(512)
+
+
+with relationships:
+
+::
+
+ Person works_for Company
+ Person commented_by Comment
+ Company commented_by Comment
+ Person concerned_by Workcase
+ Company concerned_by Workcase
+
+
+Toutes les entités ont un attribut supplémentaire 'eid', permettant
+d'identifier chaque instance de manière unique.
+
+De plus si les métadonnées sont utilisées, vous disposez pour chaque
+type d'entité des relations "creation_date", "modification_date" dont
+l'objet est une entité de type Dates (il y a un "s" pour ne pas avoir
+de conflit avec le type de base "date"), ainsi que de la relation
+"owned_by" dont l'objet est une entité de type Euser. Les schemas
+standards de ces types d'entités sont les suivants :
+
+:Dates:
+
+::
+
+ day date
+
+
+:Euser:
+
+::
+
+ login varchar(64) not null
+ firstname varchar(64)
+ surname varchar(64)
+ password password
+ role choice('admin','user','anonymous') default 'user'
+ email varchar(128)
+ web varchar(128)
+ birthday date
+
+Enfin, il existe la relation spéciale "is" permettant de spécifier le
+type d'une variable.
+
+
+Essentials
+----------
+
+1. *Alls persons*
+
+ ::
+
+ Person X ;
+ or
+ Any X WHERE X is Person ;
+
+
+2. *The company namend Logilab*
+
+ ::
+
+ Company S WHERE S name 'Logilab' ;
+
+
+3. *All entities with a name starting with 'Log'*
+
+ ::
+
+ Any S WHERE S name LIKE 'Log%' ;
+ or
+ Any S WHERE S name ~= 'Log%' ;
+
+ This query can return entities of type Person and Company.
+
+
+4. *All persons working for a company named Logilab*
+
+ ::
+
+ Person P WHERE P works_for S, S name "Logilab" ;
+ or
+ Person P WHERE P works_for S AND S name "Logilab" ;
+ or
+ Person P WHERE P works_for "Logilab" ;
+
+ La dernière forme fonctionne car "nom" est le premier attribut des
+ entités de type "Société" XXX nico: toujours vrai ?
+
+
+5. *Companies named Caesium or Logilab*
+
+ ::
+
+ Company S WHERE S name IN ('Logilab','Caesium') ;
+ or
+ Company S WHERE S name 'Logilab' OR S name 'Caesium' ;
+
+
+6. *All companies that are not named Caesium or Logilab*
+
+ ::
+
+ Company S WHERE NOT S name IN ('Logilab','Caesium') ;
+ or
+ Company S WHERE NOT S name 'Logilab' AND NOT S name 'Caesium' ;
+
+
+7. *All entities commented by the entity number 43*
+
+ ::
+
+ Any X WHERE X commented_by N, N eid 43 ;
+
+
+8. *All persons sorted by birth date in descending order*
+
+ ::
+
+ Any X WHERE X is Person, X birthdate D ORDERBY D DESC ;
+
+
+9. *All persons grouped by company*
+
+ ::
+
+ Person X WHERE X works_for S GROUPBY S,X ;
+
+ On note qu'il faut définir une variable pour s'en servir pour le
+ groupage. De plus les variables séléctionnées doivent être groupées
+ (mais les variables groupées ne doivent pas forcément être sélectionnées).
+
+XXX nico: c'est peu utile comme requête
+
+Exemples avancés
+----------------
+1. *All persons that have an empty name (i.e NULL)*
+
+ ::
+
+ Person P WHERE P name NULL ;
+
+
+2. *All persons that do not work for a company*
+
+ ::
+
+ Person P WHERE NOT P works_for S ;
+
+
+3. *All the companies that the person named 'toto' does not work for*
+
+ ::
+
+ Company S WHERE NOT P works_for S , P name 'toto' ;
+ or
+ Company S WHERE NOT 'toto' works_for S ;
+
+
+4. *All the entities modified yesterday and today*
+
+ ::
+
+ Any X WHERE X modification_date <= today, X modification_date >= today - 1
+
+
+5. *All the comments without type that required action within 7 days, sorted by date*
+
+
+ ::
+
+ Any N, D where N is Comment, N type NULL, N diem D, N diem >= today,
+ N diem < today + 7 ORDERBY D
+
+
+6. *All persons that have homonyms (each name listed only once)*
+
+ ::
+
+ Person X,Y where X name NX, Y name NX, X eid XE, Y eid > XE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/tutoriel_fr.txt Thu Dec 12 03:35:59 2019 +0100
@@ -0,0 +1,242 @@
+.. -*- coding: utf-8 -*-
+
+.. _tutorielRQL:
+
+============================================
+Tutoriel "Relation Query Language" (Hercule)
+============================================
+
+
+Apprenons RQL par la pratique...
+
+
+
+Schema
+------
+Nous supposerons dans la suite de ce document que le schéma de
+l'application est le suivant. Les différentes entités
+disponibles sont :
+
+:Personne:
+
+::
+
+ nom varchar(64) NOT NULL
+ prenom varchar(64)
+ sexe char(1) DEFAULT 'M'
+ promo choice('bon','pasbon')
+ titre varchar(128)
+ adel varchar(128)
+ web varchar(128)
+ tel integer
+ datenaiss date
+
+
+:Societe:
+
+::
+
+ nom varchar(64)
+ web varchar(128)
+ tel varchar(15)
+ adr varchar(128)
+ cp varchar(12)
+ ville varchar(32)
+
+
+:Affaire:
+
+::
+
+ sujet varchar(128)
+ ref varchar(12)
+
+
+:Note:
+
+::
+
+ diem date
+ type char(1)
+ para varchar(512)
+
+
+Et les relations entre elles:
+
+::
+
+ Person travaille_pour Societe
+ Person evaluee_par Note
+ Societe evaluee_par Note
+ Person concerne_par Note
+ Person concerne_par Affaire
+ Societe concerne_par Affaire
+
+
+Toutes les entités ont un attribut supplémentaire 'eid', permettant
+d'identifier chaque instance de manière unique.
+
+De plus si les métadonnées sont utilisées, vous disposez pour chaque
+type d'entité des relations "creation_date", "modification_date" dont
+l'objet est une entité de type Dates (il y a un "s" pour ne pas avoir
+de conflit avec le type de base "date"), ainsi que de la relation
+"owned_by" dont l'objet est une entité de type Euser. Les schemas
+standards de ces types d'entités sont les suivants :
+
+:Dates:
+
+::
+
+ day date
+
+
+:Euser:
+
+::
+
+ login varchar(64) not null
+ firstname varchar(64)
+ surname varchar(64)
+ password password
+ role choice('admin','user','anonymous') default 'user'
+ email varchar(128)
+ web varchar(128)
+ birthday date
+
+Enfin, il existe la relation spéciale "is" permettant de spécifier le
+type d'une variable.
+
+
+L'essentiel
+-----------
+1. *Toutes les personnes*
+
+ ::
+
+ Personne X ;
+ ou
+ Any X WHERE X is Personne ;
+
+
+2. *La societé nommé Logilab*
+
+ ::
+
+ Societe S WHERE S nom 'Logilab' ;
+
+
+3. *Tous les objets ayant un attribut nom commençant par 'Log'*
+
+ ::
+
+ Any S WHERE S nom LIKE 'Log%' ;
+ ou
+ Any S WHERE S nom ~= 'Log%' ;
+
+ Cette requête peut renvoyer des objets de type personne et de type
+ société.
+
+
+4. *Toutes les personnes travaillant pour la société nommé Logilab*
+
+ ::
+
+ Personne P WHERE P travaille_pour S, S nom "Logilab" ;
+ ou
+ Personne P WHERE P travaille_pour S AND S nom "Logilab" ;
+ ou
+ Personne P WHERE P travaille_pour "Logilab" ;
+
+ La dernière forme fonctionne car "nom" est le premier attribut des
+ entités de type "Société" XXX nico: toujours vrai ?
+
+
+5. *Les societés nommées Caesium ou Logilab*
+
+ ::
+
+ Societe S WHERE S nom IN ('Logilab','Caesium') ;
+ ou
+ Societe S WHERE S nom 'Logilab' OR S nom 'Caesium' ;
+
+
+6. *Toutes les societés sauf celles nommées Caesium ou Logilab*
+
+ ::
+
+ Societe S WHERE NOT S nom IN ('Logilab','Caesium') ;
+ ou
+ Societe S WHERE NOT S nom 'Logilab' AND NOT S nom 'Caesium' ;
+
+
+7. *Les objets évalués par la note d'identifiant 43*
+
+ ::
+
+ Any X WHERE X evaluee_par N, N eid 43 ;
+
+
+8. *Toutes les personnes triés par date de naissance dans l'ordre antechronologique*
+
+ ::
+
+ Any X WHERE X is Personne, X datenaiss D ORDERBY D DESC ;
+
+
+9. *Toutes les personnes groupées par leur société*
+
+ ::
+
+ Personne X WHERE X travaille_pour S GROUPBY S,X ;
+
+ On note qu'il faut définir une variable pour s'en servir pour le
+ groupage. De plus les variables séléctionnées doivent être groupées
+ (mais les variables groupées ne doivent pas forcément être sélectionnées).
+
+XXX nico: c'est peu utile comme requête
+
+Exemples avancés
+----------------
+1. *Toutes les personnes dont le champ nom n'est pas spécifié (i.e NULL)*
+
+ ::
+
+ Personne P WHERE P nom NULL ;
+
+
+2. *Toutes les personnes qui ne travaillent pour aucune société*
+
+ ::
+
+ Personne P WHERE NOT P travaille_pour S ;
+
+
+3. *Toutes les sociétés où la personne nommée toto ne travaille pas*
+
+ ::
+
+ Societe S WHERE NOT P travaille_pour S , P nom 'toto' ;
+ ou
+ Societe S WHERE NOT 'toto' travaille_pour S ;
+
+
+4. *Toutes les entités ayant été modifiées entre aujourd'hui et hier*
+
+ ::
+
+ Any X WHERE X modification_date <= today, X modification_date >= today - 1
+
+
+5. *Toutes les notes n'ayant pas de type et à effectuer dans les 7 jours, triées par date*
+
+ ::
+
+ Any N, D where N is Note, N type NULL, N diem D, N diem >= today,
+ N diem < today + 7 ORDERBY D
+
+
+6. *Les personnes ayant un homonyme (sans doublons)*
+
+ ::
+
+ Personne X,Y where X nom NX, Y nom NX, X eid XE, Y eid > XE