relational/0000755000175100017510000000000012257142102012240 5ustar salvosalvorelational/samples/0000755000175100017510000000000012257142102013704 5ustar salvosalvorelational/samples/rooms.csv0000644000175100017510000000014612257142102015561 0ustar salvosalvo"room","phone" "0","1515" "1","1516" "2","1617" "3","1601" "4","1041" "5","9212" "6","1424" "7","1294"relational/samples/person_room.csv0000644000175100017510000000011312257142102016756 0ustar salvosalvo"id","room" "0","1" "1","4" "2","2" "3","2" "4","5" "5","1" "6","5" "7","1"relational/samples/skills.csv0000644000175100017510000000030212257142102015715 0ustar salvosalvo"id","skill" "0","C" "0","Python" "1","Python" "1","C++" "1","System Admin" "2","C" "2","PHP" "3","C++" "4","C++" "4","C" "4","Perl" "5","Perl" "5","C" "7","Python" "7","C" "7","PHP" "9","Java" relational/samples/ratings.csv0000644000175100017510000000007012257142102016065 0ustar salvosalvoid,rating 0,5.3 1,6 2,5.7 3,3.3 4,9.1 5,4.4 6,5.1 7,4.9 relational/samples/people.csv0000644000175100017510000000016312257142102015705 0ustar salvosalvoid,name,chief,age 0,jack,0,22 1,carl,0,20 2,john,1,30 3,dean,1,33 4,eve,0,25 5,duncan,4,30 6,paul,4,30 7,alia,1,28 relational/samples/dates.csv0000644000175100017510000000010512257142102015515 0ustar salvosalvo"date" "2008-12-12" "2007-08-12" "1985-05-09" "1988-4-21" "1992-7-27"relational/relational.10000644000175100017510000000214712257142102014460 0ustar salvosalvo.TH "Relational" 1 "Oct 13, 2011" "Relational algebra learning tool" .SH "NAME" relational \(em Python implementation of Relational algebra. .SH "SYNOPSIS" .PP \fBrelational\fR [OPTIONS\fR\fP] [ FILE .\|.\|.] .SH "DESCRIPTION" .PP Python implementation of Relational algebra. This program provides an UI to execute relational algebra queries. It is meant to be used for educational purposes. .SH "OPTIONS" .PP These programs follow the usual GNU command line syntax, with long options starting with two dashes (`\-'). A summary of options is included below. However, the ordering is very strict \- .IP "\fB-v\fP Show version information. .IP "\fB-h\fP Shows help. .IP "\fB-q\fP Uses the Qt4 GUI (default). .IP "\fB-r\fP Uses the readline UI. .SH "AUTHOR" .PP This manual page was written by Salvo 'LtWorf' Tomaselli for the \fBDebian GNU/Linux\fP system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License version 3 or any later version published by the Free Software Foundation. relational/setup/0000755000175100017510000000000012257142102013400 5ustar salvosalvorelational/setup/installer_common.py0000644000175100017510000000222512257142102017320 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli from distutils.core import setup def c_setup(name): setup( version='1.1', name=name, packages=(name,), author="Salvo 'LtWorf' Tomaselli", author_email='tiposchi@tiscali.it', maintainer="Salvo 'LtWorf' Tomaselli", maintainer_email='tiposchi@tiscali.it', url='https://github.com/ltworf/relational', license='GPL3', ) relational/setup/relational.setup.py0000644000175100017510000000157412257142102017252 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli import installer_common installer_common.c_setup('relational_gui') #installer_common.c_setup('relational_pyside') relational/setup/python-relational.setup.py0000644000175100017510000000151512257142102020564 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli import installer_common installer_common.c_setup('relational') relational/setup/relational-cli.setup.py0000644000175100017510000000152612257142102020014 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli import installer_common installer_common.c_setup('relational_readline') relational/README0000644000175100017510000000033312257142102013117 0ustar salvosalvoTo launch the application, run ./relational_gui.py Language definition is here: https://github.com/ltworf/relational/wiki/Grammar-and-language If it needs some dependencies: Qt4, Python 2.7, either PyQT4 or Pyside. relational/relational_gui.py0000755000175100017510000001012312257142102015610 0ustar salvosalvo#!/usr/bin/env python # -*- coding: utf-8 -*- # coding=UTF-8 # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli import sys import os import os.path import getopt from relational import relation, parser version = "1.2" def printver(exit=True): print "Relational %s" % version print "Copyright (C) 2008 Salvo 'LtWorf' Tomaselli." print print "This program comes with ABSOLUTELY NO WARRANTY." print "This is free software, and you are welcome to redistribute it" print "under certain conditions." print "For details see the GPLv3 Licese." print print "Written by Salvo 'LtWorf' Tomaselli " print print "https://github.com/ltworf/relational/" if exit: sys.exit(0) def printhelp(code=0): print "Relational" print print "Usage: %s [options] [files]" % sys.argv[0] print print " -v Print version and exits" print " -h Print this help and exits" if sys.argv[0].endswith('relational-cli'): print " -q Uses QT user interface" print " -r Uses readline user interface (default)" else: print " -q Uses QT user interface (default)" print " -r Uses readline user interface" sys.exit(code) if __name__ == "__main__": if sys.argv[0].endswith('relational-cli'): x11 = False else: x11 = True # Will try to use the x11 interface # Getting command line try: switches, files = getopt.getopt(sys.argv[1:], "vhqr") except: printhelp(1) for i in switches: if i[0] == '-v': printver() elif i[0] == '-h': printhelp() elif i[0] == '-q': x11 = True elif i[0] == '-r': x11 = False if x11: import sip # needed on windows from PyQt4 import QtGui try: from relational_gui import maingui, guihandler, about, surveyForm except: print >> sys.stderr, "Module relational_gui is missing.\nPlease install relational package." sys.exit(3) about.version = version surveyForm.version = version guihandler.version = version app = QtGui.QApplication(sys.argv) app.setOrganizationName('None') app.setApplicationName('relational') ui = maingui.Ui_MainWindow() Form = guihandler.relForm(ui) # if os.name=='nt': Form.setFont(QtGui.QFont("Dejavu Sans Bold")) ui.setupUi(Form) Form.restore_settings() for i in range(len(files)): if not os.path.isfile(files[i]): print >> sys.stderr, "%s is not a file" % files[i] printhelp(12) f = files[i].split('/') defname = f[len(f) - 1].lower() if defname.endswith(".csv"): # removes the extension defname = defname[:-4] print 'Loading file "%s" with name "%s"' % (files[i], defname) Form.loadRelation(files[i], defname) Form.show() sys.exit(app.exec_()) else: printver(False) try: import relational_readline.linegui except: print >> sys.stderr, "Module relational_readline is missing.\nPlease install relational-cli package." sys.exit(3) relational_readline.linegui.version = version relational_readline.linegui.main(files) relational/complexity0000644000175100017510000001120412257142102014356 0ustar salvosalvo Complexity Abstract Purpose of this document is to describe in a detailed way the complexity of relational algebra operations. The evaluation will be done on the specific implementation of this program, not on theorical lower limits. Latest implementation can be found at: https://github.com/ltworf/relational Notation Big O notation will be used. Constant values will be ignored. Single letters will be used to indicate relations and letters between | will indicate the cardinality (number of tuples) of the relation. Number of tuples can't be enough. For example a relation with one touple and thousands of fields, will not take O(1) in general to be evaluated. So we assume that relations will have a reasonable and comparable number of fields. Then after evaluating the big O notation, an attempt to find more precise results will be done, since it will be important to know with a certain precision the weight of the operation. 1. UNARY OPERATORS Relational defines three unary operations, and they will be studied in this section. It doesn't mean that they should have similar complexity. 1.1 Selection Selection works on a relation and on a python expression. For each tuple of the relation, it will create a dictionary with name:value where name are names of the fields in the relation and value is the value for the specific row. We can consider the inner cycle as constant as its value doesn't depend on the relation itself but only on the kind of the relation (how many field it has). Then comes the evaluation. A python expression in truth could do much more things than just checking if a>b. Anyway, ssuming that nobody would ever write cycles into a selection condition, we have another constant complexity for this operation. Then, the tuple is inserted in a new relation if it satisfies the condition. Since no check on duplicated tuples is performed, this operation is constant too. In the end we have O(|n|) as complexity for a selection on the relation n. 1.2 Rename The rename operation itself is very simple, just modify the list containing the name of the fields. The big issue is to copy the content of the relation into a new relation object, so the new one can be modified. So the operation depends on the size of the relation: O(|n|). 1.3 Projection The projection operation creates a copy of the original relation using only a subset of its fields. Time for the copy is something like O(|n|) where f is the number of fields to copy. But that's not all. Since relations are set, duplicated items are not allowed. So after extracting the wanted elements, it has to check if the new tuple was already added to the new relation. And this brings the complexity to O(|n|²). But the projection can also be used to "rearrange" fields, which makes no sense in pure relational algebra, but can be usefull to make two relations match (in fact it is used internally to make relations match if they have the same fields in different order). In this case there is no need to check if the tuple already exists, because it is assumed that the relation was correct. This gives a complexity of O(|n|) in the best case. 2. BINARY OPERATORS Relational defines nine binary operations, and they will be studied in this section. Since we will deal with two relations per operation here, we will call them m and n, and f and g will be the number of their fields. 2.1 Product Product is a very complex operations. It is O(|n|*|m|). Obvious. 2.2 Intersection Same as product even if it does a different thing. But it has to compare every tuple from n with every tuple from m, to see if they match, and in this case, put them in the resulting relation. So this operation is O(|n|*|m|) as well. 2.3 Difference Same as above: 2.4 Union This operation first creates a new relation copying all the tuples from one of the originating relations, then compares them all with tuples from the other relation, and if they aren't in, they will be added. In fact it is same as above: O(|n|*|m|) 2.5 Thetajoin This operation is the combination of a product and a selection. So it is O(|n|*|m|) too. 2.6 Outher This operation is the union of the outer left and the outer right join. Makes it O(|n|*|m|) too. 2.7 Outher_left O(|n|*|m|), very depending on the number of the fields, because they are compared. 2.8 Outher_right Mirror operation of outer_lef 2.9 Join Same as above. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx relational/test/0000755000175100017510000000000012257142102013217 5ustar salvosalvorelational/test/swap_fields.result0000644000175100017510000000016312257142102016757 0ustar salvosalvoid,name,chief,age 0,jack,0,22 1,carl,0,20 2,john,1,30 3,dean,1,33 4,eve,0,25 5,duncan,4,30 6,paul,4,30 7,alia,1,28 relational/test/intersection1.query0000644000175100017510000000004312257142102017072 0ustar salvosalvoσ name=='eve' (people) ᑎ people relational/test/pswap.result0000644000175100017510000000000512257142102015604 0ustar salvosalvoTrue relational/test/union_or_select.query0000644000175100017510000000005112257142102017471 0ustar salvosalvoσ age<21 (people) ᑌ σage >30(people) relational/test/rename_insert1.exec0000644000175100017510000000020212257142102016773 0ustar salvosalvop1=people.rename({"id":"ido"}) people.insert((123,"lala",0,31)) print p1 print people retval=people==p1 people.delete("id==123") relational/test/name_age.result0000644000175100017510000000012312257142102016207 0ustar salvosalvoname,age eve,25 dean,33 carl,20 paul,30 john,30 jack,22 duncan,30 alia,28 relational/test/union1.query0000644000175100017510000000007012257142102015514 0ustar salvosalvoσ age<30 (σ (id%2==0) (people) ᑌ σ age>22(people)) relational/test/union4.result0000644000175100017510000000016312257142102015673 0ustar salvosalvoid,name,chief,age 0,jack,0,22 1,carl,0,20 2,john,1,30 3,dean,1,33 4,eve,0,25 5,duncan,4,30 6,paul,4,30 7,alia,1,28 relational/test/skill_of_best_person.result0000644000175100017510000000006312257142102020663 0ustar salvosalvoname,age,skill eve,25,Perl eve,25,C eve,25,C++ relational/test/maxdate.query0000644000175100017510000000006212257142102015727 0ustar salvosalvodates-πdate(σ d>date (ρdate➡d(dates)*dates)) relational/test/maxdate.result0000644000175100017510000000002212257142102016074 0ustar salvosalvodate 2008-12-12 relational/test/intersection2.query0000644000175100017510000000004312257142102017073 0ustar salvosalvopeople ᑎ σ name=='eve' (people) relational/test/union3.query0000644000175100017510000000004312257142102015516 0ustar salvosalvoσ name=='eve' (people) ᑌ people relational/test/younger.query0000644000175100017510000000011612257142102015774 0ustar salvosalvopeople-π id,name,chief,age(σ age>a(π a(ρ id➡i,age➡a(people))*people)) relational/test/older_than_boss.result0000644000175100017510000000020412257142102017620 0ustar salvosalvoname,age,chief_name,chief_age dean,33,carl,20 alia,28,carl,20 paul,30,eve,25 eve,25,jack,22 john,30,carl,20 duncan,30,eve,25 relational/test/c_programmers.result0000644000175100017510000000014512257142102017317 0ustar salvosalvoid,name,chief,age,skill 2,john,1,30,C 7,alia,1,28,C 5,duncan,4,30,C 0,jack,0,22,C 4,eve,0,25,C relational/test/dates.query0000644000175100017510000000000612257142102015402 0ustar salvosalvodates relational/test/union_or_select.result0000644000175100017510000000005512257142102017646 0ustar salvosalvoid,name,chief,age 3,dean,1,33 1,carl,0,20 relational/test/max_rating_in_age_range.query0000644000175100017510000000037212257142102021117 0ustar salvosalvo(σ age<25(people) ᑌ σ age>30(people)) ᐅᐊ ratings-πid,name,chief,age,rating(σ rating30(people)) ᐅᐊ ratings))) * (σ age<25(people) ᑌ σ age>30(people)) ᐅᐊ ratings))relational/test/subtraction1.query0000644000175100017510000000004012257142102016716 0ustar salvosalvopeople - σ name=='eve'(people) relational/test/subtraction2.result0000644000175100017510000000002312257142102017071 0ustar salvosalvoid,name,chief,age relational/test/dates_sel.query0000644000175100017510000000005512257142102016251 0ustar salvosalvoσ date.year>2000 and date.day+10<30 (dates) relational/test/select_join_opt.result0000644000175100017510000000006612257142102017641 0ustar salvosalvoid,name,chief,age,skill 0,jack,0,22,C 4,eve,0,25,C relational/test/redoundant_union_select.query0000644000175100017510000000005212257142102021215 0ustar salvosalvoσ (id==2) (σ age>5 (people ᑌ people)) relational/test/people.query0000644000175100017510000000000712257142102015567 0ustar salvosalvopeople relational/test/max_rating_in_age_range.result0000644000175100017510000000005112257142102021262 0ustar salvosalvoid,name,chief,age,rating 1,carl,0,20,6 relational/test/phones_of_people_with_personal_room.query0000644000175100017510000000024712257142102023627 0ustar salvosalvoπname,phone(((πname,id(people)- π name,id(πid(σ i!=id and room==r(ρ id➡i,room➡r(person_room)*person_room)) ᐅᐊ people)) ᐅᐊ person_room) ᐅᐊ rooms) relational/test/rename_insert2.result0000644000175100017510000000002112257142102017365 0ustar salvosalvo{'retval':False} relational/test/dates.result0000644000175100017510000000010512257142102015553 0ustar salvosalvo"date" "2008-12-12" "2007-08-12" "1985-05-09" "1988-4-21" "1992-7-27"relational/test/c_programmers.query0000644000175100017510000000004412257142102017144 0ustar salvosalvoσ skill=='C'(people ᐅᐊ skills) relational/test/people_join_select_args_on_both_tables.result0000644000175100017510000000004612257142102024377 0ustar salvosalvoid,name,chief,age,skill 0,jack,0,22,C relational/test/swap_fields.query0000644000175100017510000000003712257142102016606 0ustar salvosalvoπ name,id,age,chief (people) relational/test/rel_eq.python0000644000175100017510000000001712257142102015727 0ustar salvosalvopeople=='ciao' relational/test/union4.query0000644000175100017510000000003512257142102015520 0ustar salvosalvopeople ᑌ people ᑎ people relational/test/union2.result0000644000175100017510000000017412257142102015673 0ustar salvosalvoid,name,chief,age 3,dean,1,33 6,paul,4,30 2,john,1,30 0,jack,0,22 7,alia,1,28 1,carl,0,20 4,eve,0,25 5,duncan,4,30 relational/test/people_join_select_args_on_both_tables.query0000644000175100017510000000007712257142102024232 0ustar salvosalvoσ skill=='C' and age<25 and skill!=name(people ᐅᐊ skills) relational/test/php.result0000644000175100017510000000005212257142102015243 0ustar salvosalvoid,name,chief,age,skill 7,alia,1,28,PHP relational/test/union3.result0000644000175100017510000000017412257142102015674 0ustar salvosalvoid,name,chief,age 3,dean,1,33 6,paul,4,30 2,john,1,30 0,jack,0,22 7,alia,1,28 1,carl,0,20 4,eve,0,25 5,duncan,4,30 relational/test/dates_sel.result0000644000175100017510000000003612257142102016421 0ustar salvosalvodate 2008-12-12 2007-08-12 relational/test/select_join_opt.query0000644000175100017510000000012612257142102017465 0ustar salvosalvoσ skill=='C' and chief==0 ((σ age<30 (people) ᑌ σ age>40(people)) ᐅᐊ skills) relational/test/phones_of_people_with_personal_room.result0000644000175100017510000000002512257142102023772 0ustar salvosalvophone,name 1041,carl relational/test/rename_insert2.exec0000644000175100017510000000017612257142102017006 0ustar salvosalvop1=people.rename({"id":"ido"}) p1.insert((123,"lala",0,31)) print p1 print people retval=people==p1 people.delete("id==123") relational/test/union_not_select.query0000644000175100017510000000005412257142102017654 0ustar salvosalvoσ skill=='C' (skills) - σ id%2==0(skills) relational/test/php.query0000644000175100017510000000006212257142102015073 0ustar salvosalvoσ age<30 and skill=='PHP' (people ᐅᐊ skills) relational/test/union1.result0000644000175100017510000000007112257142102015666 0ustar salvosalvoid,name,chief,age 7,alia,1,28 4,eve,0,25 0,jack,0,22 relational/test/intersection1.result0000644000175100017510000000003712257142102017246 0ustar salvosalvoid,name,chief,age 4,eve,0,25 relational/test/fixed_len_name.result0000644000175100017510000000034012257142102017411 0ustar salvosalvoid,name,chief,age,skill 2,john,1,30,C 7,alia,1,28,C 1,carl,0,20,C++ 2,john,1,30,PHP 7,alia,1,28,Python 3,dean,1,33,C++ 7,alia,1,28,PHP 0,jack,0,22,Python 1,carl,0,20,Python 0,jack,0,22,C 1,carl,0,20,System Admin relational/test/rel_eq.result0000644000175100017510000000000612257142102015722 0ustar salvosalvoFalse relational/test/union_not_select.result0000644000175100017510000000002412257142102020022 0ustar salvosalvoid,skill 5,C 7,C relational/test/union_and_select.query0000644000175100017510000000005612257142102017620 0ustar salvosalvoσ skill=='C'(skills) ᑎ σ id%2==0 (skills) relational/test/fixed_len_name.query0000644000175100017510000000005012257142102017236 0ustar salvosalvoσ (len(name)==4)(peopleᐅᐊ skills) relational/test/intersection2.result0000644000175100017510000000003712257142102017247 0ustar salvosalvoid,name,chief,age 4,eve,0,25 relational/test/skill_of_best_person.query0000644000175100017510000000017612257142102020517 0ustar salvosalvoπname,age,skill((ratings-πid,rating(σ r>rating (ρrating➡r(πrating(ratings )) * ratings)) ᐅᐊ people) ᐅᐊ skills) relational/test/subtraction1.result0000644000175100017510000000016012257142102017072 0ustar salvosalvoid,name,chief,age 3,dean,1,33 6,paul,4,30 2,john,1,30 0,jack,0,22 7,alia,1,28 1,carl,0,20 5,duncan,4,30 relational/test/subtraction2.query0000644000175100017510000000003112257142102016717 0ustar salvosalvoσ age>15(people)-people relational/test/people.result0000644000175100017510000000016312257142102015743 0ustar salvosalvoid,name,chief,age 0,jack,0,22 1,carl,0,20 2,john,1,30 3,dean,1,33 4,eve,0,25 5,duncan,4,30 6,paul,4,30 7,alia,1,28 relational/test/younger.result0000644000175100017510000000003612257142102016146 0ustar salvosalvoid,age,chief,name 1,20,0,carl relational/test/union2.query0000644000175100017510000000004312257142102015515 0ustar salvosalvopeople ᑌ σ name=='eve' (people) relational/test/union_and_select.result0000644000175100017510000000003112257142102017762 0ustar salvosalvoid,skill 0,C 2,C 4,C relational/test/older_than_boss.query0000644000175100017510000000020712257142102017452 0ustar salvosalvoρn➡chief_name,a➡chief_age(πname,age,n,a(σ i==chief and age>a (π i,c,n,a(ρage➡a,id➡i,chief➡c,name➡n(people))*people))) relational/test/rename_insert1.result0000644000175100017510000000002112257142102017364 0ustar salvosalvo{'retval':False} relational/test/redoundant_union_select.result0000644000175100017510000000003612257142102021370 0ustar salvosalvoid,name,chief,age 2,john,1,30 relational/test/pswap.python0000644000175100017510000000006512257142102015615 0ustar salvosalvopeople.projection("name","id","age","chief")==people relational/test/name_age.query0000644000175100017510000000010712257142102016040 0ustar salvosalvoρn➡name,a➡age(πn,a(ρid➡i,name➡n,chief➡c,age➡a(people))) relational/CREDITS0000644000175100017510000000027612257142102013265 0ustar salvosalvoOri Avtalion for suggesting some improvements Chris Lamb for being interested Emilio Di Prima for the windows port Konstantin Lepa (for the termcolor module) relational/relational_pyside/0000755000175100017510000000000012257142102015747 5ustar salvosalvorelational/relational_pyside/survey.ui0000777000175100017510000000000012257142102024745 2../relational_gui/survey.uiustar salvosalvorelational/relational_pyside/survey.py0000644000175100017510000001745712257142102017674 0ustar salvosalvo# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'relational_pyside/survey.ui' # # Created: Fri Dec 27 00:23:51 2013 # by: pyside-uic 0.2.15 running on PySide 1.2.1 # # WARNING! All changes made in this file will be lost! from PySide import QtCore, QtGui class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(422, 313) Form.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.verticalLayout = QtGui.QVBoxLayout(Form) self.verticalLayout.setObjectName("verticalLayout") self.formLayout = QtGui.QGridLayout() self.formLayout.setObjectName("formLayout") self.txtSystem = QtGui.QLineEdit(Form) self.txtSystem.setObjectName("txtSystem") self.formLayout.addWidget(self.txtSystem, 0, 1, 1, 1) self.label = QtGui.QLabel(Form) self.label.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label.setObjectName("label") self.formLayout.addWidget(self.label, 1, 0, 1, 1) self.txtCountry = QtGui.QLineEdit(Form) self.txtCountry.setObjectName("txtCountry") self.formLayout.addWidget(self.txtCountry, 1, 1, 1, 1) self.label_2 = QtGui.QLabel(Form) self.label_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_2.setObjectName("label_2") self.formLayout.addWidget(self.label_2, 2, 0, 1, 1) self.txtSchool = QtGui.QLineEdit(Form) self.txtSchool.setObjectName("txtSchool") self.formLayout.addWidget(self.txtSchool, 2, 1, 1, 1) self.label_3 = QtGui.QLabel(Form) self.label_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_3.setObjectName("label_3") self.formLayout.addWidget(self.label_3, 3, 0, 1, 1) self.txtAge = QtGui.QLineEdit(Form) self.txtAge.setObjectName("txtAge") self.formLayout.addWidget(self.txtAge, 3, 1, 1, 1) self.label_4 = QtGui.QLabel(Form) self.label_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_4.setObjectName("label_4") self.formLayout.addWidget(self.label_4, 4, 0, 1, 1) self.txtFind = QtGui.QLineEdit(Form) self.txtFind.setObjectName("txtFind") self.formLayout.addWidget(self.txtFind, 4, 1, 1, 1) self.label_5 = QtGui.QLabel(Form) self.label_5.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_5.setObjectName("label_5") self.formLayout.addWidget(self.label_5, 0, 0, 1, 1) self.label_6 = QtGui.QLabel(Form) self.label_6.setObjectName("label_6") self.formLayout.addWidget(self.label_6, 6, 0, 1, 1) self.txtComments = QtGui.QTextEdit(Form) self.txtComments.setTabChangesFocus(True) self.txtComments.setObjectName("txtComments") self.formLayout.addWidget(self.txtComments, 6, 1, 1, 1) self.label_7 = QtGui.QLabel(Form) self.label_7.setObjectName("label_7") self.formLayout.addWidget(self.label_7, 5, 0, 1, 1) self.txtEmail = QtGui.QLineEdit(Form) self.txtEmail.setObjectName("txtEmail") self.formLayout.addWidget(self.txtEmail, 5, 1, 1, 1) self.verticalLayout.addLayout(self.formLayout) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.cmdCancel = QtGui.QPushButton(Form) self.cmdCancel.setObjectName("cmdCancel") self.horizontalLayout.addWidget(self.cmdCancel) self.cmdClear = QtGui.QPushButton(Form) self.cmdClear.setObjectName("cmdClear") self.horizontalLayout.addWidget(self.cmdClear) self.cmdSend = QtGui.QPushButton(Form) self.cmdSend.setDefault(True) self.cmdSend.setObjectName("cmdSend") self.horizontalLayout.addWidget(self.cmdSend) self.verticalLayout.addLayout(self.horizontalLayout) self.label.setBuddy(self.txtCountry) self.label_2.setBuddy(self.txtSchool) self.label_3.setBuddy(self.txtAge) self.label_4.setBuddy(self.txtFind) self.label_5.setBuddy(self.txtSystem) self.label_6.setBuddy(self.txtComments) self.label_7.setBuddy(self.txtEmail) self.retranslateUi(Form) QtCore.QObject.connect(self.cmdCancel, QtCore.SIGNAL("clicked()"), Form.close) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL("clicked()"), self.txtComments.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL("clicked()"), self.txtFind.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL("clicked()"), self.txtAge.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL("clicked()"), self.txtSchool.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL("clicked()"), self.txtCountry.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL("clicked()"), self.txtSystem.clear) QtCore.QObject.connect(self.txtSystem, QtCore.SIGNAL("returnPressed()"), self.txtCountry.setFocus) QtCore.QObject.connect(self.txtCountry, QtCore.SIGNAL("returnPressed()"), self.txtSchool.setFocus) QtCore.QObject.connect(self.txtSchool, QtCore.SIGNAL("returnPressed()"), self.txtAge.setFocus) QtCore.QObject.connect(self.txtAge, QtCore.SIGNAL("returnPressed()"), self.txtFind.setFocus) QtCore.QObject.connect(self.cmdSend, QtCore.SIGNAL("clicked()"), Form.send) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL("clicked()"), self.txtEmail.clear) QtCore.QObject.connect(self.txtFind, QtCore.SIGNAL("returnPressed()"), self.txtEmail.setFocus) QtCore.QObject.connect(self.txtEmail, QtCore.SIGNAL("returnPressed()"), self.txtComments.setFocus) QtCore.QMetaObject.connectSlotsByName(Form) Form.setTabOrder(self.txtSystem, self.txtCountry) Form.setTabOrder(self.txtCountry, self.txtSchool) Form.setTabOrder(self.txtSchool, self.txtAge) Form.setTabOrder(self.txtAge, self.txtFind) Form.setTabOrder(self.txtFind, self.txtEmail) Form.setTabOrder(self.txtEmail, self.txtComments) Form.setTabOrder(self.txtComments, self.cmdSend) Form.setTabOrder(self.cmdSend, self.cmdClear) Form.setTabOrder(self.cmdClear, self.cmdCancel) def retranslateUi(self, Form): Form.setWindowTitle(QtGui.QApplication.translate("Form", "Survey", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate("Form", "Country", None, QtGui.QApplication.UnicodeUTF8)) self.label_2.setText(QtGui.QApplication.translate("Form", "School", None, QtGui.QApplication.UnicodeUTF8)) self.label_3.setText(QtGui.QApplication.translate("Form", "Age", None, QtGui.QApplication.UnicodeUTF8)) self.label_4.setText(QtGui.QApplication.translate("Form", "How did you find relational", None, QtGui.QApplication.UnicodeUTF8)) self.label_5.setText(QtGui.QApplication.translate("Form", "System", None, QtGui.QApplication.UnicodeUTF8)) self.label_6.setText(QtGui.QApplication.translate("Form", "Comments", None, QtGui.QApplication.UnicodeUTF8)) self.label_7.setText(QtGui.QApplication.translate("Form", "Email (only if you want a reply)", None, QtGui.QApplication.UnicodeUTF8)) self.cmdCancel.setText(QtGui.QApplication.translate("Form", "Cancel", None, QtGui.QApplication.UnicodeUTF8)) self.cmdClear.setText(QtGui.QApplication.translate("Form", "Clear", None, QtGui.QApplication.UnicodeUTF8)) self.cmdSend.setText(QtGui.QApplication.translate("Form", "Send", None, QtGui.QApplication.UnicodeUTF8)) relational/relational_pyside/rel_edit.ui0000777000175100017510000000000012257142102025431 2../relational_gui/rel_edit.uiustar salvosalvorelational/relational_pyside/surveyForm.py0000777000175100017510000000000012257142102026443 2../relational_gui/surveyForm.pyustar salvosalvorelational/relational_pyside/maingui.pyc0000644000175100017510000003571712257142102020132 0ustar salvosalvo Rc@s0ddlmZmZdefdYZdS(i(tQtCoretQtGuit Ui_MainWindowcBseZdZdZRS(cCs|jd|jddtj||_|jjdtj|j|_|jjdtj|j|_|jj t j j |jjdtj|j|_ |j jdtj|j |_|jjdddd|jjd tj|j |_|jjd tj|j|_|jjd tj|j|_|jjd |jj|jtj|j|_|jjd |jj|j|jj|jtj|j |_|jjdtj|j|_|jjdtj|j|_|jjd|jj|jtj|j|_|jjd|jj|jtj|j|_|jjd|jj|jtj|j|_|jjd|jj|jtj|j|_|jjd|jj|jtj|j|_|jjd|jj|jtj|j|_|jjd|jj|jtj|j|_ |j jd|jj|j tj|j|_!|j!jd|jj|j!tj|j|_"|j"jd|jj|j"tj|j|_#|j#jd|jj|j#tj|j|_$|j$jd|jj|j$tj|j|_%|j%jd|jj|j%tj&ddtj'j(tj'j)}|jj*||jj|jtj|j|_+|j+j t j j |j+jdtj|j+|_,|j,j t j j-|j,jd tj.|j,|_/|j/j0t j1d!d"|j/j2t j1dd|j/j3t4|j/jd#|j/j5j6dd$tj|j,|_7|j7jd%tj|j7|_8|j8j9tj:j;|j8jdddd|j8jd&tj<|j7|_=tj'tj'j)tj'j>}|j?d|j@d|jA|j=jBjC|j=jD||j=jEt j1d'd'|j=jFt j1ddtjG}|jHt4|j=jI||j=jd(|j8j|j=tjJ|_K|jKjd)tj|j7|_L|jLjd*|jKj|jLtj|j7|_M|jMjd+|jKj|jMtj|j7|_N|jNjd,|jKj|jN|j8jO|jKtj|j+|_P|jPj t j j-|jPjd-tj|jP|_Q|jQj0t j1dd|jQjEt j1d.d'|jQjd/tj|jQ|_R|jRjd0tj<|jQ|_Stj'tj'j>tj'j)}|j?d|j@d|jA|jSjBjC|jSjD||jSjEt j1d'd'|jSjd1|jRj|jStj|jQ|_T|jTjd2|jRj|jTtj|jQ|_U|jUjd3|jRj|jUtj|jQ|_V|jVjd4|jRj|jVtj|jQ|_W|jWjd5|jRj|jWtj|jQ|_X|jXjd6|jRj|jXtj|jP|_Y|jYj0t j1dd|jYjEt j1d.d'|jYjd7tj|jY|_Z|jZjd8tj<|jY|_[tj'tj'j>tj'j)}|j?d|j@d|jA|j[jBjC|j[jD||j[jEt j1d'd'|j[jd9|jZj|j[|jj|jtjJ|_\|j\jd:tj]|j|_^tj'tj'j>tj'j_}|j?d|j@d|jA|j^jBjC|j^jD||j^jd;|j\j|j^tj`|j|_a|jajd<|j\j|jatj]|j|_b|jbjd=|j\j|jbtj|j|_c|jcjd>|j\j|jctj|j|_d|jdjd?|j\j|jd|jjO|j\|je|jtjf||_g|jgjht jidddd@|jgjdAtjj|jg|_k|jkjdBtjj|jg|_l|jljdCtjm||_n|jnjdDtjj|jg|_o|jojdE|jp|jgtjm||_q|jqjrtjmjs|jqjdFtjm||_t|jtjdGtjm||_u|jujdHtjm||_v|jvjrtjmjw|jvjdItjm||_x|jxjdJtjm||_y|jyjdKtjm||_z|jzjdLtjm||_{|j{jdMtjm||_||j|jdNtjm||_}|j}jdOtjm||_~|j~jdP|jkj|jkj|jv|jlj|jq|jlj|jx|joj|jy|joj|jt|joj|ju|joj|jz|joj|j~|jgj|jkj|jgj|joj|jgj|jlj|jaj|jb|j|t jj|jct jdQ|jbjt jj|jNt jdQ|j=jt jj|jbt jdR|jt jj|jdt jdQ|jt jj|jt jdQ|jt jj|jt jdQ|jt jj|jt jdQ|jt jj|jt jdQ|jt jj|j%t jdQ|jt jj|j$t jdQ|jt jj|j#t jdQ|jt jj|j"t jdQ|jt jj|jXt jdQ|jt jj|jVt jdQ|jt jj|jUt jdQ|jt jj|jLt jdQ|jt jj|jMt jdQ|jt jj|j^t jdR|jbjt jj|j t jdQ|jt jj|j!t jdQ|jt jj|jt jdQ|jt jj|jt jdQ|jt jj|jt jdQ|jt jj|jt jdQ|jt jj|jt jdQ|jt jj|jSt jdS|jt jj|jSt jdT|jt jj|jct jdQ|jbjt jj|j=t jdS|jt jj|jqt jdU|jt jj|jtt jdU|jt jj|jut jdU|jt jj|jvt jdU|jt jj|jxt jdU|jt jj|jWt jdQ|jt jj|jzt jdU|jt jj|jTt jdQ|jt jj|jyt jdU|jt jj|j~t jdU|jt jj||j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j|j |j|j |j!|j|j!|j"|j|j"|j#|j|j#|j$|j|j$|j%|j|j%|j/|j|j/|j=|j|j=|jL|j|jL|jM|j|jM|jN|j|jN|jS|j|jS|jU|j|jU|jV|j|jV|jX|j|jX|j[|j|j[|j^|j|j^|jb|j|jb|jc|j|jc|jddS(VNt MainWindowi idt centralwidgettverticalLayout_7t splitter_4t layoutWidgetitverticalLayout_11t groupBox_3tverticalLayout_5tcmdAboutt cmdSurveyt groupBox_4tverticalLayout_10t cmdProductt cmdDifferencetcmdUniontcmdIntersectiont cmdDivisiontcmdJoint cmdOuterLeftt cmdOuterRighttcmdOutert cmdProjectiont cmdSelectiont cmdRenametcmdArrowiit splitter_3t splitter_2iittablesEmpty relationt layoutWidget1tverticalLayout_6it lstHistorythorizontalLayout_3t cmdOptimizetcmdUndoOptimizetcmdClearHistorytsplitteri,tgroupBoxtverticalLayoutt lstRelationstcmdNewtcmdLoadtcmdSavetcmdEditt cmdUnloadt groupBox_2tverticalLayout_3t lstAttributesthorizontalLayout_2t txtResulttlabelttxtQueryt cmdClearQueryt cmdExecuteitmenubartmenuFilet menuAbouttactiont menuRelationst actionAbouttaction_Load_relationtaction_Save_relationt action_QuittactionCheck_for_new_versionstactionNew_relationtactionEdit_relationtactionNew_sessiontactionSave_session_astactionManage_sessionstactionUnload_relations clicked()sreturnPressed()s#itemDoubleClicked(QListWidgetItem*)sitemClicked(QListWidgetItem*)s triggered()(t setObjectNametresizeRtQWidgetRt QVBoxLayoutRt QSplitterRtsetOrientationRtQtt HorizontalRRtsetContentsMarginst QGroupBoxR R t QPushButtonR t addWidgetR R RRRRRRRRRRRRRRt QSpacerItemt QSizePolicytMinimumt ExpandingtaddItemRRtVerticalt QTreeWidgetRtsetMinimumSizetQSizetsetSizeIncrementtsetRootIsDecoratedtFalset headerItemtsetTextRR tsetSizeConstrainttQLayouttSetMinimumSizet QListWidgetR!t PreferredtsetHorizontalStretchtsetVerticalStretchtsetHeightForWidtht sizePolicythasHeightForWidtht setSizePolicytsetMaximumSizet setBaseSizetQFontt setStrikeOuttsetFontt QHBoxLayoutR"R#R$R%t addLayoutR&R'R(R)R*R+R,R-R.R/R0R1R2t QLineEditR3tFixedtQLabelR4R5R6R7tsetCentralWidgettQMenuBarR8t setGeometrytQRecttQMenuR9R:tQActionR;R<t setMenuBarR=t setMenuRolet AboutRoleR>R?R@tQuitRoleRARBRCRDRERFRGt addSeparatort addActiont menuActiontsetBuddyt retranslateUitQObjecttconnecttSIGNALtcleartexecutet showAboutt showSurveyt addProductt addDifferencetaddArrowt addRenamet addSelectiont addProjectiontunloadRelationt saveRelationt loadRelationtoptimizet undoOptimizetsetFocust addORighttaddOutertaddOLefttaddJoint addDivisiontaddIntersectiontaddUniont printRelationtshowAttributest resumeHistorytcloset checkVersiont editRelationt newRelationt QMetaObjecttconnectSlotsByNamet setTabOrder(tselfRt spacerItemRjtfont((s7/home/salvo/dev/relational/relational_pyside/maingui.pytsetupUi sb $          "  ((%%%%%%%%%%%%%%%(%%%%%%%%%(%%%%%%%%%%%cCs |jtjjdddtjj|jjtjjdddtjj|jj tjjdddtjj|j j tjjdddtjj|j jtjjdddtjj|j j tjjdddtjj|j j tjjdddtjj|jj tjjdd dtjj|jj tjjdd dtjj|jj tjjdd dtjj|jj tjjdd dtjj|jj tjjdd dtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdddtjj|jj tjjdd dtjj|jj tjjdd!dtjj|jj tjjdd"dtjj|jjtjjdd#dtjj|jjt |j!j tjjdd$dtjj|j"j tjjdd%dtjj|j#j tjjdd&dtjj|j$j tjjdd'dtjj|j%j tjjdd(dtjj|j&jtjjdd)dtjj|j'j tjjdd*dtjj|j(j tjjdd+dtjj|j)j tjjdd,dtjj|j*j tjjdd-dtjj|j+jtjjdd.dtjj|j,jtjjdd/dtjj|j-jtjjdd#dtjj|j.j tjjdd0dtjj|j/j tjjdd1dtjj|j/j0tjjdd2dtjj|j1j tjjdd3dtjj|j1j0tjjdd4dtjj|j2j tjjdd5dtjj|j2j0tjjdd6dtjj|j3j tjjdd7dtjj|j4j tjjdd$dtjj|j4j0tjjdd8dtjj|j5j tjjdd'dtjj|j5j0tjjdd9dtjj|j6j tjjdd:dtjj|j7j tjjdd;dtjj|j7j tjjdd;dtjj|j8j tjjdd<dtjj|j9j tjjdd(dtjjdS(=NRt RelationaltMenutAbouttSurveyt OperatorstProductt*t Differencet-tUnionsᑌt IntersectionsᑎtDivisions÷s Natural joinsᐅᐊsLeft outer joins ᐅLEFTᐊsRight outer joins ᐅRIGHTᐊsFull outer joins ᐅFULLᐊt Projectionsπt SelectionsσtRenamesρs➡tOptimizes Undo optimizes Clear historyt Relationss New relations Load relations Save relations Edit relationsUnload relationt Attributest_last1t=s⌫tExecutes&Files&Helps&Abouts&Load relationsCtrl+Os&Save relationsCtrl+Ss&QuitsCtrl+QsCheck for new versionssCtrl+NsCtrl+Es New sessionsSave session assManage sessions(:tsetWindowTitleRt QApplicationt translatetNonet UnicodeUTF8R tsetTitleR RaR R Rt setToolTipRRRRRRRRRRRRR#R$R%R'R)tsetSortingEnabledtTrueR*R+R,R-R.R/R3R4R6R7R9R:R<R=R>t setShortcutR?R@RARBRCRDRERFRG(RR((s7/home/salvo/dev/relational/relational_pyside/maingui.pyRAs(++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++(t__name__t __module__RR(((s7/home/salvo/dev/relational/relational_pyside/maingui.pyR s 5N(tPySideRRtobjectR(((s7/home/salvo/dev/relational/relational_pyside/maingui.pyt srelational/relational_pyside/survey.pyc0000644000175100017510000001217412257142102020026 0ustar salvosalvo Rc@s0ddlmZmZdefdYZdS(i(tQtCoretQtGuitUi_FormcBseZdZdZRS(cCs |jd|jdd|jtjtjjtjjtj||_ |j jdtj |_ |j jdtj ||_ |j jd|j j|j ddddtj||_|jjtjtjjtjj|jjd |j j|jddddtj ||_|jjd |j j|jddddtj||_|jjtjtjjtjj|jjd |j j|jd dddtj ||_|jjd |j j|jd dddtj||_|jjtjtjjtjj|jjd|j j|jddddtj ||_|jjd|j j|jddddtj||_|jjtjtjjtjj|jjd|j j|jddddtj ||_|jjd|j j|jddddtj||_|jjtjtjjtjj|jjd|j j|jddddtj||_|jjd|j j|jddddtj||_|jjt|jjd|j j|jddddtj||_|jjd|j j|jddddtj ||_|jjd|j j|jdddd|j j |j tj!|_"|j"jdtj#ddtj$j%tj$j&}|j"j'|tj(||_)|j)jd|j"j|j)tj(||_*|j*jd|j"j|j*tj(||_+|j+j,t|j+jd |j"j|j+|j j |j"|jj-|j|jj-|j|jj-|j|jj-|j|jj-|j |jj-|j|jj-|j|j.|tj/j0|j)tj1d!|j2tj/j0|j*tj1d!|jj3tj/j0|j*tj1d!|jj3tj/j0|j*tj1d!|jj3tj/j0|j*tj1d!|jj3tj/j0|j*tj1d!|jj3tj/j0|j*tj1d!|j j3tj/j0|j tj1d"|jj4tj/j0|jtj1d"|jj4tj/j0|jtj1d"|jj4tj/j0|jtj1d"|jj4tj/j0|j+tj1d!|j5tj/j0|j*tj1d!|jj3tj/j0|jtj1d"|jj4tj/j0|jtj1d"|jj4tj6j7||j8|j |j|j8|j|j|j8|j|j|j8|j|j|j8|j|j|j8|j|j|j8|j|j+|j8|j+|j*|j8|j*|j)dS(#NtFormii9tverticalLayoutt formLayoutt txtSystemiitlabelt txtCountrytlabel_2it txtSchooltlabel_3ittxtAgetlabel_4ittxtFindtlabel_5tlabel_6it txtCommentstlabel_7ittxtEmailthorizontalLayouti(it cmdCanceltcmdCleartcmdSends clicked()sreturnPressed()(9t setObjectNametresizet setLocaleRtQLocaletEnglisht UnitedStatesRt QVBoxLayoutRt QGridLayoutRt QLineEditRt addWidgettQLabelRRR R R R R RRRt QTextEditRtsetTabChangesFocustTrueRRt addLayoutt QHBoxLayoutRt QSpacerItemt QSizePolicyt ExpandingtMinimumtaddItemt QPushButtonRRRt setDefaulttsetBuddyt retranslateUitQObjecttconnecttSIGNALtclosetcleartsetFocustsendt QMetaObjecttconnectSlotsByNamet setTabOrder(tselfRt spacerItem((s6/home/salvo/dev/relational/relational_pyside/survey.pytsetupUi s %((((($ %((((((((((%(((cCs|jtjjdddtjj|jjtjjdddtjj|jjtjjdddtjj|j jtjjdddtjj|j jtjjdddtjj|j jtjjdddtjj|j jtjjdddtjj|j jtjjdd dtjj|jjtjjdd dtjj|jjtjjdd dtjj|jjtjjdd dtjjdS( NRtSurveytCountrytSchooltAgesHow did you find relationaltSystemtCommentss Email (only if you want a reply)tCanceltCleartSend(tsetWindowTitleRt QApplicationt translatetNonet UnicodeUTF8RtsetTextR R R RRRRRR(R;R((s6/home/salvo/dev/relational/relational_pyside/survey.pyR0xs(+++++++++(t__name__t __module__R=R0(((s6/home/salvo/dev/relational/relational_pyside/survey.pyR s kN(tPySideRRtobjectR(((s6/home/salvo/dev/relational/relational_pyside/survey.pyt srelational/relational_pyside/surveyForm.pyc0000644000175100017510000002407112257142102020651 0ustar salvosalvo NRc@syddlmZmZWnddlmZmZnXddlZddlmZddlZddlZdej fdYZ dS(i(tQtCoretQtGuiN(t maintenancet surveyFormcBs)eZdZdZdZdZRS(sThis class is the form used for the survey, needed to intercept the events. It also sends the data with http POST to a pagecCs ||_dS(N(tui(tselfR((s:/home/salvo/dev/relational/relational_pyside/surveyForm.pytsetUi#scCsfidd6dd6dd6dd6d d 6d d 6d d6dd6dd6dd6dd6dd6dd6dd6dd6dd 6d!d"6d#d$6d%d&6d'd(6d)d*6d+d,6d-d.6d/d06d1d26d3d46d5d66d7d86d9d:6d;d<6d=d>6d?d@6dAdB6dCdD6dEdF6dGdH6dIdJ6dKdL6dMdN6dOdP6dQdR6dSdT6dUdV6dWdX6dYdZ6d[d\6d]d^6d_d`6dadb6dcdd6dedf6dgdh6didj6dkdl6dmdn6dodp6dqdr6dsdt6dudv6dwdx6dydz6d{d|6d}d~6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6d d 6d d 6d d6dd6dd6dd6dd6dd6dd6dd6dd6dd 6d!d"6d#d$6d%d&6d'd(6d)d*6d+d,6d-d.6d/d06d1d26d3d46d5d66d7d86d9d:6d;d<6d=d>6d?d@6dAdB6dCdD6dEdF6dGdH6dIdJ6dKdL6dMdN6dOdP6dQdR6dSdT6dUdV6dWdX6dYdZ6d[d\6d]d^6d_d`6dadb6dcdd6dedf6dgdh6didj6dkdl6dmdn6dodp6dqdr6dsdt6dudv6dwdx6dydz6d{d|6d}d~6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6}y0|jjjtj|jjjdWnnXy^tjtjdtjdj dd}|jj j|||jj jdWnnXdS(sfSets default values into the form GUI. It has to be called after the form has been initializedt BANGLADESHtBDtBELGIUMtBEs BURKINA FASOtBFtBULGARIAtBGsBOSNIA AND HERZEGOVINAtBAtBARBADOStBBsWALLIS AND FUTUNAtWFsSAINT BARTHÉLEMYtBLtBERMUDAtBMsBRUNEI DARUSSALAMtBNsBOLIVIA, PLURINATIONAL STATE OFtBOtBAHRAINtBHtBURUNDItBItBENINtBJtBHUTANtBTtJAMAICAtJMs BOUVET ISLANDtBVtBOTSWANAtBWtSAMOAtWStBRAZILtBRtBAHAMAStBStJERSEYtJEtBELARUStBYtBELIZEtBZsRUSSIAN FEDERATIONtRUtRWANDAtRWtSERBIAtRSs TIMOR-LESTEtTLsRÉUNIONtREt TURKMENISTANtTMt TAJIKISTANtTJtROMANIAtROtTOKELAUtTKs GUINEA-BISSAUtGWtGUAMtGUt GUATEMALAtGTs,SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDStGStGREECEtGRsEQUATORIAL GUINEAtGQt GUADELOUPEtGPtJAPANtJPtGUYANAtGYtGUERNSEYtGGs FRENCH GUIANAtGFtGEORGIAtGEtGRENADAtGDsUNITED KINGDOMtGBtGABONtGAtGUINEAtGNtGAMBIAtGMt GREENLANDtGLt GIBRALTARtGItGHANAtGHtOMANtOMtTUNISIAtTNtJORDANtJOtCROATIAtHRtHAITItHTtHUNGARYtHUs HONG KONGtHKtHONDURAStHNs!HEARD ISLAND AND MCDONALD ISLANDStHMs!VENEZUELA, BOLIVARIAN REPUBLIC OFtVEs PUERTO RICOtPRsPALESTINIAN TERRITORY, OCCUPIEDtPStPALAUtPWtPORTUGALtPTsSAINT KITTS AND NEVIStKNtPARAGUAYtPYtIRAQtIQtPANAMAtPAsFRENCH POLYNESIAtPFsPAPUA NEW GUINEAtPGtPERUtPEtPAKISTANtPKt PHILIPPINEStPHtPITCAIRNtPNtPOLANDtPLsSAINT PIERRE AND MIQUELONtPMtZAMBIAtZMsWESTERN SAHARAtEHtESTONIAtEEtEGYPTtEGs SOUTH AFRICAtZAtECUADORtECtITALYtITsVIET NAMtVNsSOLOMON ISLANDStSBtETHIOPIAtETtSOMALIAtSOtZIMBABWEtZWs SAUDI ARABIAtSAtSPAINtEStERITREAtERt MONTENEGROtMEsMOLDOVA, REPUBLIC OFtMDt MADAGASCARtMGs SAINT MARTINtMFtMOROCCOtMAtMONACOtMCt UZBEKISTANtUZtMYANMARtMMtMALItMLtMACAOtMOtMONGOLIAtMNsMARSHALL ISLANDStMHs*MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OFtMKt MAURITIUStMUtMALTAtMTtMALAWItMWtMALDIVEStMVt MARTINIQUEtMQsNORTHERN MARIANA ISLANDStMPt MONTSERRATtMSt MAURITANIAtMRs ISLE OF MANtIMtUGANDAtUGsTANZANIA, UNITED REPUBLIC OFtTZtMALAYSIAtMYtMEXICOtMXtISRAELtILtFRANCEtFRtARUBAtAWs SAINT HELENAtSHsSVALBARD AND JAN MAYENtSJtFINLANDtFItFIJItFJsFALKLAND ISLANDS (MALVINAS)tFKsMICRONESIA, FEDERATED STATES OFtFMs FAROE ISLANDStFOt NICARAGUAtNIt NETHERLANDStNLtNORWAYtNOtNAMIBIAtNAtVANUATUtVUs NEW CALEDONIAtNCtNIGERtNEsNORFOLK ISLANDtNFtNIGERIAtNGs NEW ZEALANDtNZtNEPALtNPtNAURUtNRtNIUEtNUs COOK ISLANDStCKsCÔTE D'IVOIREtCIt SWITZERLANDtCHtCOLOMBIAtCOtCHINAtCNtCAMEROONtCMtCHILEtCLsCOCOS (KEELING) ISLANDStCCtCANADAtCAtCONGOtCGsCENTRAL AFRICAN REPUBLICtCFs%CONGO, THE DEMOCRATIC REPUBLIC OF THEtCDsCZECH REPUBLICtCZtCYPRUStCYsCHRISTMAS ISLANDtCXs COSTA RICAtCRs CAPE VERDEtCVtCUBAtCUt SWAZILANDtSZsSYRIAN ARAB REPUBLICtSYt KYRGYZSTANtKGtKENYAtKEtSURINAMEtSRtKIRIBATItKItCAMBODIAtKHs EL SALVADORtSVtCOMOROStKMsSAO TOME AND PRINCIPEtSTtSLOVAKIAtSKsKOREA, REPUBLIC OFtKRtSLOVENIAtSIs&KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OFtKPtKUWAITtKWtSENEGALtSNs SAN MARINOtSMs SIERRA LEONEtSLt SEYCHELLEStSCt KAZAKHSTANtKZsCAYMAN ISLANDStKYt SINGAPOREtSGtSWEDENtSEtSUDANtSDsDOMINICAN REPUBLICtDOtDOMINICAtDMtDJIBOUTItDJtDENMARKtDKsVIRGIN ISLANDS, BRITISHtVGtGERMANYtDEtYEMENtYEtALGERIAtDZs UNITED STATEStUStURUGUAYtUYtMAYOTTEtYTs$UNITED STATES MINOR OUTLYING ISLANDStUMtLEBANONtLBs SAINT LUCIAtLCs LAO PEOPLE'S DEMOCRATIC REPUBLICtLAtTUVALUtTVsTAIWAN, PROVINCE OF CHINAtTWsTRINIDAD AND TOBAGOtTTtTURKEYtTRs SRI LANKAtLKt LIECHTENSTEINtLItLATVIAtLVtTONGAtTOt LITHUANIAtLTt LUXEMBOURGtLUtLIBERIAtLRtLESOTHOtLStTHAILANDtTHsFRENCH SOUTHERN TERRITORIEStTFtTOGOtTGtCHADtTDsTURKS AND CAICOS ISLANDStTCsLIBYAN ARAB JAMAHIRIYAtLYsHOLY SEE (VATICAN CITY STATE)tVAs SAINT VINCENT AND THE GRENADINEStVCsUNITED ARAB EMIRATEStAEtANDORRAtADsANTIGUA AND BARBUDAtAGt AFGHANISTANtAFtANGUILLAtAIsVIRGIN ISLANDS, U.S.tVItICELANDtISsIRAN, ISLAMIC REPUBLIC OFtIRtARMENIAtAMtALBANIAtALtANGOLAtAOsNETHERLANDS ANTILLEStANt ANTARCTICAtAQsAMERICAN SAMOAtASt ARGENTINAtARt AUSTRALIAtAUtAUSTRIAtATsBRITISH INDIAN OCEAN TERRITORYtIOtINDIAtINsÅLAND ISLANDStAXt AZERBAIJANtAZtIRELANDtIEt INDONESIAtIDtUKRAINEtUAtQATARtQAt MOZAMBIQUEtMZitt_iN( Rt txtSystemtsetTexttplatformtsetCursorPositiontlocalet setlocaletLC_ALLt getlocaletsplitt txtCountry(Rt countriest country_code((s:/home/salvo/dev/relational/relational_pyside/surveyForm.pytsetDefaultValues&s(GcCsi}d|ds   relational/relational_pyside/guihandler.py0000777000175100017510000000000012257142102026345 2../relational_gui/guihandler.pyustar salvosalvorelational/relational_pyside/creator.py0000777000175100017510000000000012257142102025177 2../relational_gui/creator.pyustar salvosalvorelational/relational_pyside/__init__.pyc0000644000175100017510000000021712257142102020223 0ustar salvosalvo Rc@sdS(N((((s8/home/salvo/dev/relational/relational_pyside/__init__.pytsrelational/relational_pyside/about.pyc0000644000175100017510000017073412257142102017612 0ustar salvosalvo Rc@s&ddlZyDddlmZmZyddlmZeZWn eZnXWnGddlmZmZyddlmZeZWn eZnXnXdZ de fdYZ e dkr"ddl Z eje jZejZe Zejeeje jejndS(iN(tQtCoretQtGui(tQtWebKitit Ui_DialogcBseZdZdZRS(cCs"|jd|jddtj||_|jjdtj||_|jjdtj|_|jj t j dddd|jjd tj|j|_ |j jd tj |j|_|jjd tj|j|_|jjd tj|j|_tj}|jd |jj||jjd|jj|jtj|j|_|jjd|jj|j|j j|jtj |j|_|jjdtj|j|_|jjdtj|j|_|jjd|jj|j|j j|jtj |j|_|jjdtj|j|_|jjdtj|j|_|jjd|jj|j|j j|j|jj|jdtj|_|jj t j dddd|jjdtj|j|_|jjdtj |j|_!|j!jd|jj|j!|jj|jdtj|_"|j"jdtj|j"|_#|j#jdt$rOt%j&|j"|_'|j'j(t j)d|j'jd|j#j|j'ntj|j|_*|j*j||j*jd|j*j+tj,j-ddd|j*j/t0|j*j1t j2j3|j*j4t j2j5t j2j6Bt j2j7Bt j2j8Bt j2j9B|j#j|j*|jj|j"d|jj|jtj:||_;|j;j<t j2j=|j;j>tj:j?|j;jd |jj|j;|j@||jjAdt jBjC|j;t jDd!|jEt jBjC|j;t jDd"|jFt jGjH|dS(#NtDialogiitverticalLayout_2t tabWidgetiiiyttabtverticalLayout_3tgroupBoxtverticalLayout_5itlabeltlabel_3t groupBox_3tverticalLayout_4tlabel_2t groupBox_2tverticalLayout_6tlabel_4ttLicensetverticalLayoutttextEditttab_2tverticalLayout_7s>https://github.com/ltworf/relational/wiki/Grammar-and-languagetwebViewtlblLinksGRelational's websitet buttonBoxs accepted()s rejected()(It setObjectNametresizeRt QVBoxLayoutRt QTabWidgetRtQWidgetRt setGeometryRtQRectRt QGroupBoxR R tQLabelR tQFontt setPointSizetsetFontt addWidgetR R RRRRRtaddTabRRt QTextEditRRRtwebkRtQWebViewRtsetUrltQUrltwebLinktsetTextt QApplicationt translatetNonetsetOpenExternalLinkstTruet setTextFormattQttAutoTexttsetTextInteractionFlagstLinksAccessibleByKeyboardtLinksAccessibleByMousetTextBrowserInteractiontTextSelectableByKeyboardtTextSelectableByMousetQDialogButtonBoxRtsetOrientationt HorizontaltsetStandardButtonstOkt retranslateUitsetCurrentIndextQObjecttconnecttSIGNALtaccepttrejectt QMetaObjecttconnectSlotsByName(tselfRtfont((s5/home/salvo/dev/relational/relational_pyside/about.pytsetupUi+s "  "  '   cCs|jtjjdddtjj|jjtjjdddtjj|jj tjjdddtjj|j j tjjddt dtjj|j j t jjt jjB|jjtjjdddtjj|jj tjjdddtjj|jjt|jj t jjt jjB|jjtjjdddtjj|jj tjjdddtjj|jjt|jj t jjt jjB|jj|jj|jtjjdd dtjj|jjtjjdd dtjj|jj|jj|jtjjdd dtjj|jj|jj|jtjjdd dtjjdS( NRt Documentationt RelationalsVersion tAuthorsSalvo "LtWorf" Tomaselli <tiposchi@tiscali.it>
Emilio Di Prima <emiliodiprima[at]msn[dot]com> (For the windows setup)tLinkssYhttps://github.com/ltworf/relational/tAboutsr GNU General Public License - GNU Project - Free Software Foundation (FSF)

GNU GENERAL PUBLIC LICENSE

Version 3, 29 June 2007

Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>

Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble

The GNU General Public License is a free, copyleft license for software and other kinds of works.

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.

To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.

Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.

Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS

0. Definitions.

“This License” refers to version 3 of the GNU General Public License.

“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.

“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.

To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.

A “covered work” means either the unmodified Program or a work based on the Program.

To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.

To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.

An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.

1. Source Code.

The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.

A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.

The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.

The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.

The Corresponding Source for a work in source code form is that same work.

2. Basic Permissions.

All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.

You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.

Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

3. Protecting Users' Legal Rights From Anti-Circumvention Law.

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.

When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.

4. Conveying Verbatim Copies.

You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.

You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.

5. Conveying Modified Source Versions.

You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:

  • a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
  • b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
  • c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
  • d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.

A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

6. Conveying Non-Source Forms.

You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:

  • a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
  • b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
  • c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
  • d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
  • e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.

A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.

A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.

“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.

If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).

The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.

Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.

7. Additional Terms.

“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.

When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.

Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:

  • a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
  • b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
  • c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
  • d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
  • e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
  • f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.

All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.

If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.

Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.

8. Termination.

You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.

9. Acceptance Not Required for Having Copies.

You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.

10. Automatic Licensing of Downstream Recipients.

Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.

An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.

11. Patents.

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.

A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.

Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.

If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.

A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.

Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

12. No Surrender of Others' Freedom.

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.

13. Use with the GNU Affero General Public License.

Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.

14. Revised Versions of this License.

The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.

If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.

15. Disclaimer of Warranty.

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. Limitation of Liability.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

17. Interpretation of Sections 15 and 16.

If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. 

Also add information on how to contact you by electronic and paper mail.

If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details. 

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.

The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.

RtDocs(tsetWindowTitleRR1R2R3t UnicodeUTF8R tsetTitleR R0R tversionR9RR7R;R>R RR4R5RRRt setTabTexttindexOfRRtsetHtmlRR(RMR((s5/home/salvo/dev/relational/relational_pyside/about.pyRDs@   $$$(t__name__t __module__RORD(((s5/home/salvo/dev/relational/relational_pyside/about.pyR)s `t__main__(tostPyQt4RRRR5R+tFalsetPySideRYtobjectRR]tsysR1targvtapptQDialogRtuiROtshowtexittexec_(((s5/home/salvo/dev/relational/relational_pyside/about.pyts2         relational/relational_pyside/compatibility.pyc0000644000175100017510000000305512257142102021340 0ustar salvosalvo Rc@sny ddlmZmZeZWn#ddlmZmZeZnXdZdZdZ dZ dS(i(tQtCoretQtGuicCstrt|jdS|S(s(Returns a python string out of a QStringsutf-8(tpyqttunicodettoUtf8(ta((s=/home/salvo/dev/relational/relational_pyside/compatibility.pyt get_py_strscCs3ts|j|n|jtjj|dS(N(RtsetTextRtQStringtfromUtf8(t componentttext((s=/home/salvo/dev/relational/relational_pyside/compatibility.pyt set_utf8_text&scCstrt|jS|dS(Ni(RtstrR(tfilename((s=/home/salvo/dev/relational/relational_pyside/compatibility.pyt get_filename-scCstr[tj}|j|tjdd}|j||j||j |n9tjdd}|j||j||j |dS(Ni( RRRtappendRtQListWidgetItemtNoneRtaddItemtsetCurrentItem(tltitemt history_itemthitem((s=/home/salvo/dev/relational/relational_pyside/compatibility.pyt add_list_item3s      N( tPyQt4RRtTrueRtPySidetFalseRR RR(((s=/home/salvo/dev/relational/relational_pyside/compatibility.pyts     relational/relational_pyside/rel_edit.py0000644000175100017510000000766312257142102020124 0ustar salvosalvo# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'relational_pyside/rel_edit.ui' # # Created: Fri Dec 27 00:23:51 2013 # by: pyside-uic 0.2.15 running on PySide 1.2.1 # # WARNING! All changes made in this file will be lost! from PySide import QtCore, QtGui class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(594, 444) self.verticalLayout_2 = QtGui.QVBoxLayout(Dialog) self.verticalLayout_2.setObjectName("verticalLayout_2") self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.groupBox = QtGui.QGroupBox(Dialog) self.groupBox.setObjectName("groupBox") self.verticalLayout = QtGui.QVBoxLayout(self.groupBox) self.verticalLayout.setObjectName("verticalLayout") self.cmdAddTuple = QtGui.QPushButton(self.groupBox) self.cmdAddTuple.setObjectName("cmdAddTuple") self.verticalLayout.addWidget(self.cmdAddTuple) self.cmdRemoveTuple = QtGui.QPushButton(self.groupBox) self.cmdRemoveTuple.setObjectName("cmdRemoveTuple") self.verticalLayout.addWidget(self.cmdRemoveTuple) self.cmdAddColumn = QtGui.QPushButton(self.groupBox) self.cmdAddColumn.setObjectName("cmdAddColumn") self.verticalLayout.addWidget(self.cmdAddColumn) self.cmdRemoveColumn = QtGui.QPushButton(self.groupBox) self.cmdRemoveColumn.setObjectName("cmdRemoveColumn") self.verticalLayout.addWidget(self.cmdRemoveColumn) self.horizontalLayout.addWidget(self.groupBox) self.table = QtGui.QTableWidget(Dialog) self.table.setObjectName("table") self.table.setColumnCount(0) self.table.setRowCount(0) self.horizontalLayout.addWidget(self.table) self.verticalLayout_2.addLayout(self.horizontalLayout) self.label = QtGui.QLabel(Dialog) self.label.setObjectName("label") self.verticalLayout_2.addWidget(self.label) self.buttonBox = QtGui.QDialogButtonBox(Dialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName("buttonBox") self.verticalLayout_2.addWidget(self.buttonBox) self.retranslateUi(Dialog) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), Dialog.reject) QtCore.QObject.connect(self.cmdAddColumn, QtCore.SIGNAL("clicked()"), Dialog.addColumn) QtCore.QObject.connect(self.cmdRemoveColumn, QtCore.SIGNAL("clicked()"), Dialog.deleteColumn) QtCore.QObject.connect(self.cmdAddTuple, QtCore.SIGNAL("clicked()"), Dialog.addRow) QtCore.QObject.connect(self.cmdRemoveTuple, QtCore.SIGNAL("clicked()"), Dialog.deleteRow) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Relation editor", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox.setTitle(QtGui.QApplication.translate("Dialog", "Edit", None, QtGui.QApplication.UnicodeUTF8)) self.cmdAddTuple.setText(QtGui.QApplication.translate("Dialog", "Add tuple", None, QtGui.QApplication.UnicodeUTF8)) self.cmdRemoveTuple.setText(QtGui.QApplication.translate("Dialog", "Remove tuple", None, QtGui.QApplication.UnicodeUTF8)) self.cmdAddColumn.setText(QtGui.QApplication.translate("Dialog", "Add column", None, QtGui.QApplication.UnicodeUTF8)) self.cmdRemoveColumn.setText(QtGui.QApplication.translate("Dialog", "Remove column", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate("Dialog", "Remember that new relations and modified relations are not automatically saved", None, QtGui.QApplication.UnicodeUTF8)) relational/relational_pyside/compatibility.py0000777000175100017510000000000012257142102027623 2../relational_gui/compatibility.pyustar salvosalvorelational/relational_pyside/maingui.ui0000777000175100017510000000000012257142102025135 2../relational_gui/maingui.uiustar salvosalvorelational/relational_pyside/about.py0000777000175100017510000000000012257142102024325 2../relational_gui/about.pyustar salvosalvorelational/relational_pyside/guihandler.pyc0000644000175100017510000003261212257142102020612 0ustar salvosalvo Rc@sddlZddlZddlZyddlmZmZWnddlmZmZnXddlmZm Z m Z m Z ddl Z ddl Z ddlZddlZddlZdejfdYZdS(iN(tQtCoretQtGui(trelationtparsert optimizertrtypestrelFormcBsIeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZd#d#dZdZdZdZdZdZdZdZdZdZ dZ!dZ"d Z#d!Z$d"Z%RS($cCsbtjj|d|_d|_i|_d|_d|_||_ d|_ t j |_ dS(Ni(Rt QMainWindowt__init__tNonetAbouttSurveyt relationstundotselectedRelationtuitqcounterRt QSettingstsettings(tselfR((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyR(s       cCsddlm}|j}|tkrDtjjdd|}n9|tkrhtjjdd}ntjjdd}tjj|tjjdd|dS(Ni(t maintenancetForms!New version available online: %s.sLatest version installed.s"You are using an unstable version.tVersion( t relationalRtcheck_latest_versiontversionRt QApplicationt translatet QMessageBoxt information(RRtonlinetr((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyt checkVersion4s        cGs-|jjj|jj|djdS(Ni(RttxtQuerytsetTexttsavedQtitemDatattoString(Rtindex((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyt load_queryEscCs,|jdkr(|jjj|jndS(sIUndoes the optimization on the query, popping one item from the undo listN(R R RR!R"(R((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyt undoOptimizeHscCs|jjj|_tj|jjj}y/tj||j}tj |jj|WnWt k r}t j j dt jjdddt jjdd|jfnXdS(s4Performs all the possible optimizations on the queryRtErrors%s %ssCheck your query!N(RR!ttextR t compatibilityt get_py_strRt optimize_allR t set_utf8_textt ExceptionRRRR RRt__str__(Rtquerytresultte((s:/home/salvo/dev/relational/relational_pyside/guihandler.pytoptimizeMs!cCsYtj|jjdd}tj|jj|dtj|jj|ddS(Ns = ii(R+R,R*tsplitR.Rt txtResultR!(Rtitemtitm((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyt resumeHistoryYs!cCstj|jjj}tj|jjj}tj|s}tj j |tj j ddtj j dddSybt j|}|GdG|GHt||j}||j|<|j||_|j|jWnctk rD}|jGHtj j dtj j dddtj j dd|jfdSXdtj|jjjtj|jjjf}tj|jj||jd 7_tj|jjd |jdS( sExecutes the queryRR)s$Wrong name for destination relation.Ns-->u%s %ssCheck your query!u%s = %siu_last%d(R+R,RR!R*R6Rtis_valid_relation_nameRRRRRRtparsetevalR tupdateRelationsRt showRelationR/t __unicode__R t add_list_itemt lstHistoryRR.(RR1tres_reltexprR2R3R7((s:/home/salvo/dev/relational/relational_pyside/guihandler.pytexecute^s4     !# 1cCs2|jjj|dkrO|jjjd|jjjjdddS|jjjt|jj xa|j D]V}t j }x.t t|D]}|j|||qW|jjj|qxWxYt t|jj D]?}|jjjj||jj ||jjj|qWdS(s*Shows the selected relation into the tableiisEmpty relationN(RttabletclearR tsetColumnCountt headerItemR"tlentheadert attributestcontentRtQTreeWidgetItemtrangetaddTopLevelItemtresizeColumnToContents(RtreltiR7tj((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyR>s  & cCs3|jtj|j|_|j|jdS(N(R R+R,R*RR>(RR7((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyt printRelationscCsZtj|j}|jjjx.|j|jjD]}|jjj |q9WdS(s-Shows the attributes of the selected relationN( R+R,R*Rt lstAttributesRFR RJRKtaddItem(RR7RQRS((s:/home/salvo/dev/relational/relational_pyside/guihandler.pytshowAttributesscCsJ|jjjx3|jD](}|dkr|jjj|qqWdS(Nt __builtins__(Rt lstRelationsRFR RV(RRR((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyR=s cCsrtjj|tjjdddtjjdd}tj|}t|dkr^dS|jj |dS(NRs Save RelationtsRelations (*.csv)i( Rt QFileDialogtgetSaveFileNameRRR+t get_filenameRIRtsave(Rtfilename((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyt saveRelations$cCsDx3|jjjD]}|jtj|j=qW|jdS(N(RRYt selectedItemsR R+R,R*R=(RRR((s:/home/salvo/dev/relational/relational_pyside/guihandler.pytunloadRelationscCsddl}xj|jjjD]V}|j|jtj|j}|dkr||jtj|jRTRWR=R`RbReRnRrRoRsR{RR RRRRRRRRRRRRRRR(((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyR&sF     (      #    0             (tsystostpickletPyQt4RRtPySideRRRRRR}RuRttmainguiR+RR(((s:/home/salvo/dev/relational/relational_pyside/guihandler.pyts   "     relational/relational_pyside/__init__.py0000777000175100017510000000000012257142102025377 2../relational_gui/__init__.pyustar salvosalvorelational/relational_pyside/maingui.py0000644000175100017510000006775412257142102017775 0ustar salvosalvo# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'relational_pyside/maingui.ui' # # Created: Fri Dec 27 00:23:51 2013 # by: pyside-uic 0.2.15 running on PySide 1.2.1 # # WARNING! All changes made in this file will be lost! from PySide import QtCore, QtGui class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 612) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout_7 = QtGui.QVBoxLayout(self.centralwidget) self.verticalLayout_7.setObjectName("verticalLayout_7") self.splitter_4 = QtGui.QSplitter(self.centralwidget) self.splitter_4.setOrientation(QtCore.Qt.Horizontal) self.splitter_4.setObjectName("splitter_4") self.layoutWidget = QtGui.QWidget(self.splitter_4) self.layoutWidget.setObjectName("layoutWidget") self.verticalLayout_11 = QtGui.QVBoxLayout(self.layoutWidget) self.verticalLayout_11.setContentsMargins(0, 0, 0, 0) self.verticalLayout_11.setObjectName("verticalLayout_11") self.groupBox_3 = QtGui.QGroupBox(self.layoutWidget) self.groupBox_3.setObjectName("groupBox_3") self.verticalLayout_5 = QtGui.QVBoxLayout(self.groupBox_3) self.verticalLayout_5.setObjectName("verticalLayout_5") self.cmdAbout = QtGui.QPushButton(self.groupBox_3) self.cmdAbout.setObjectName("cmdAbout") self.verticalLayout_5.addWidget(self.cmdAbout) self.cmdSurvey = QtGui.QPushButton(self.groupBox_3) self.cmdSurvey.setObjectName("cmdSurvey") self.verticalLayout_5.addWidget(self.cmdSurvey) self.verticalLayout_11.addWidget(self.groupBox_3) self.groupBox_4 = QtGui.QGroupBox(self.layoutWidget) self.groupBox_4.setObjectName("groupBox_4") self.verticalLayout_10 = QtGui.QVBoxLayout(self.groupBox_4) self.verticalLayout_10.setObjectName("verticalLayout_10") self.cmdProduct = QtGui.QPushButton(self.groupBox_4) self.cmdProduct.setObjectName("cmdProduct") self.verticalLayout_10.addWidget(self.cmdProduct) self.cmdDifference = QtGui.QPushButton(self.groupBox_4) self.cmdDifference.setObjectName("cmdDifference") self.verticalLayout_10.addWidget(self.cmdDifference) self.cmdUnion = QtGui.QPushButton(self.groupBox_4) self.cmdUnion.setObjectName("cmdUnion") self.verticalLayout_10.addWidget(self.cmdUnion) self.cmdIntersection = QtGui.QPushButton(self.groupBox_4) self.cmdIntersection.setObjectName("cmdIntersection") self.verticalLayout_10.addWidget(self.cmdIntersection) self.cmdDivision = QtGui.QPushButton(self.groupBox_4) self.cmdDivision.setObjectName("cmdDivision") self.verticalLayout_10.addWidget(self.cmdDivision) self.cmdJoin = QtGui.QPushButton(self.groupBox_4) self.cmdJoin.setObjectName("cmdJoin") self.verticalLayout_10.addWidget(self.cmdJoin) self.cmdOuterLeft = QtGui.QPushButton(self.groupBox_4) self.cmdOuterLeft.setObjectName("cmdOuterLeft") self.verticalLayout_10.addWidget(self.cmdOuterLeft) self.cmdOuterRight = QtGui.QPushButton(self.groupBox_4) self.cmdOuterRight.setObjectName("cmdOuterRight") self.verticalLayout_10.addWidget(self.cmdOuterRight) self.cmdOuter = QtGui.QPushButton(self.groupBox_4) self.cmdOuter.setObjectName("cmdOuter") self.verticalLayout_10.addWidget(self.cmdOuter) self.cmdProjection = QtGui.QPushButton(self.groupBox_4) self.cmdProjection.setObjectName("cmdProjection") self.verticalLayout_10.addWidget(self.cmdProjection) self.cmdSelection = QtGui.QPushButton(self.groupBox_4) self.cmdSelection.setObjectName("cmdSelection") self.verticalLayout_10.addWidget(self.cmdSelection) self.cmdRename = QtGui.QPushButton(self.groupBox_4) self.cmdRename.setObjectName("cmdRename") self.verticalLayout_10.addWidget(self.cmdRename) self.cmdArrow = QtGui.QPushButton(self.groupBox_4) self.cmdArrow.setObjectName("cmdArrow") self.verticalLayout_10.addWidget(self.cmdArrow) spacerItem = QtGui.QSpacerItem(20, 25, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout_10.addItem(spacerItem) self.verticalLayout_11.addWidget(self.groupBox_4) self.splitter_3 = QtGui.QSplitter(self.splitter_4) self.splitter_3.setOrientation(QtCore.Qt.Horizontal) self.splitter_3.setObjectName("splitter_3") self.splitter_2 = QtGui.QSplitter(self.splitter_3) self.splitter_2.setOrientation(QtCore.Qt.Vertical) self.splitter_2.setObjectName("splitter_2") self.table = QtGui.QTreeWidget(self.splitter_2) self.table.setMinimumSize(QtCore.QSize(450, 400)) self.table.setSizeIncrement(QtCore.QSize(0, 0)) self.table.setRootIsDecorated(False) self.table.setObjectName("table") self.table.headerItem().setText(0, "Empty relation") self.layoutWidget1 = QtGui.QWidget(self.splitter_2) self.layoutWidget1.setObjectName("layoutWidget1") self.verticalLayout_6 = QtGui.QVBoxLayout(self.layoutWidget1) self.verticalLayout_6.setSizeConstraint(QtGui.QLayout.SetMinimumSize) self.verticalLayout_6.setContentsMargins(0, 0, 0, 0) self.verticalLayout_6.setObjectName("verticalLayout_6") self.lstHistory = QtGui.QListWidget(self.layoutWidget1) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lstHistory.sizePolicy().hasHeightForWidth()) self.lstHistory.setSizePolicy(sizePolicy) self.lstHistory.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.lstHistory.setBaseSize(QtCore.QSize(0, 0)) font = QtGui.QFont() font.setStrikeOut(False) self.lstHistory.setFont(font) self.lstHistory.setObjectName("lstHistory") self.verticalLayout_6.addWidget(self.lstHistory) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.cmdOptimize = QtGui.QPushButton(self.layoutWidget1) self.cmdOptimize.setObjectName("cmdOptimize") self.horizontalLayout_3.addWidget(self.cmdOptimize) self.cmdUndoOptimize = QtGui.QPushButton(self.layoutWidget1) self.cmdUndoOptimize.setObjectName("cmdUndoOptimize") self.horizontalLayout_3.addWidget(self.cmdUndoOptimize) self.cmdClearHistory = QtGui.QPushButton(self.layoutWidget1) self.cmdClearHistory.setObjectName("cmdClearHistory") self.horizontalLayout_3.addWidget(self.cmdClearHistory) self.verticalLayout_6.addLayout(self.horizontalLayout_3) self.splitter = QtGui.QSplitter(self.splitter_3) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setObjectName("splitter") self.groupBox = QtGui.QGroupBox(self.splitter) self.groupBox.setMinimumSize(QtCore.QSize(0, 0)) self.groupBox.setMaximumSize(QtCore.QSize(300, 16777215)) self.groupBox.setObjectName("groupBox") self.verticalLayout = QtGui.QVBoxLayout(self.groupBox) self.verticalLayout.setObjectName("verticalLayout") self.lstRelations = QtGui.QListWidget(self.groupBox) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lstRelations.sizePolicy().hasHeightForWidth()) self.lstRelations.setSizePolicy(sizePolicy) self.lstRelations.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.lstRelations.setObjectName("lstRelations") self.verticalLayout.addWidget(self.lstRelations) self.cmdNew = QtGui.QPushButton(self.groupBox) self.cmdNew.setObjectName("cmdNew") self.verticalLayout.addWidget(self.cmdNew) self.cmdLoad = QtGui.QPushButton(self.groupBox) self.cmdLoad.setObjectName("cmdLoad") self.verticalLayout.addWidget(self.cmdLoad) self.cmdSave = QtGui.QPushButton(self.groupBox) self.cmdSave.setObjectName("cmdSave") self.verticalLayout.addWidget(self.cmdSave) self.cmdEdit = QtGui.QPushButton(self.groupBox) self.cmdEdit.setObjectName("cmdEdit") self.verticalLayout.addWidget(self.cmdEdit) self.cmdUnload = QtGui.QPushButton(self.groupBox) self.cmdUnload.setObjectName("cmdUnload") self.verticalLayout.addWidget(self.cmdUnload) self.groupBox_2 = QtGui.QGroupBox(self.splitter) self.groupBox_2.setMinimumSize(QtCore.QSize(0, 0)) self.groupBox_2.setMaximumSize(QtCore.QSize(300, 16777215)) self.groupBox_2.setObjectName("groupBox_2") self.verticalLayout_3 = QtGui.QVBoxLayout(self.groupBox_2) self.verticalLayout_3.setObjectName("verticalLayout_3") self.lstAttributes = QtGui.QListWidget(self.groupBox_2) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lstAttributes.sizePolicy().hasHeightForWidth()) self.lstAttributes.setSizePolicy(sizePolicy) self.lstAttributes.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.lstAttributes.setObjectName("lstAttributes") self.verticalLayout_3.addWidget(self.lstAttributes) self.verticalLayout_7.addWidget(self.splitter_4) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.txtResult = QtGui.QLineEdit(self.centralwidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.txtResult.sizePolicy().hasHeightForWidth()) self.txtResult.setSizePolicy(sizePolicy) self.txtResult.setObjectName("txtResult") self.horizontalLayout_2.addWidget(self.txtResult) self.label = QtGui.QLabel(self.centralwidget) self.label.setObjectName("label") self.horizontalLayout_2.addWidget(self.label) self.txtQuery = QtGui.QLineEdit(self.centralwidget) self.txtQuery.setObjectName("txtQuery") self.horizontalLayout_2.addWidget(self.txtQuery) self.cmdClearQuery = QtGui.QPushButton(self.centralwidget) self.cmdClearQuery.setObjectName("cmdClearQuery") self.horizontalLayout_2.addWidget(self.cmdClearQuery) self.cmdExecute = QtGui.QPushButton(self.centralwidget) self.cmdExecute.setObjectName("cmdExecute") self.horizontalLayout_2.addWidget(self.cmdExecute) self.verticalLayout_7.addLayout(self.horizontalLayout_2) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 19)) self.menubar.setObjectName("menubar") self.menuFile = QtGui.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.menuAbout = QtGui.QMenu(self.menubar) self.menuAbout.setObjectName("menuAbout") self.action = QtGui.QAction(MainWindow) self.action.setObjectName("action") self.menuRelations = QtGui.QMenu(self.menubar) self.menuRelations.setObjectName("menuRelations") MainWindow.setMenuBar(self.menubar) self.actionAbout = QtGui.QAction(MainWindow) self.actionAbout.setMenuRole(QtGui.QAction.AboutRole) self.actionAbout.setObjectName("actionAbout") self.action_Load_relation = QtGui.QAction(MainWindow) self.action_Load_relation.setObjectName("action_Load_relation") self.action_Save_relation = QtGui.QAction(MainWindow) self.action_Save_relation.setObjectName("action_Save_relation") self.action_Quit = QtGui.QAction(MainWindow) self.action_Quit.setMenuRole(QtGui.QAction.QuitRole) self.action_Quit.setObjectName("action_Quit") self.actionCheck_for_new_versions = QtGui.QAction(MainWindow) self.actionCheck_for_new_versions.setObjectName("actionCheck_for_new_versions") self.actionNew_relation = QtGui.QAction(MainWindow) self.actionNew_relation.setObjectName("actionNew_relation") self.actionEdit_relation = QtGui.QAction(MainWindow) self.actionEdit_relation.setObjectName("actionEdit_relation") self.actionNew_session = QtGui.QAction(MainWindow) self.actionNew_session.setObjectName("actionNew_session") self.actionSave_session_as = QtGui.QAction(MainWindow) self.actionSave_session_as.setObjectName("actionSave_session_as") self.actionManage_sessions = QtGui.QAction(MainWindow) self.actionManage_sessions.setObjectName("actionManage_sessions") self.actionUnload_relation = QtGui.QAction(MainWindow) self.actionUnload_relation.setObjectName("actionUnload_relation") self.menuFile.addSeparator() self.menuFile.addAction(self.action_Quit) self.menuAbout.addAction(self.actionAbout) self.menuAbout.addAction(self.actionCheck_for_new_versions) self.menuRelations.addAction(self.actionNew_relation) self.menuRelations.addAction(self.action_Load_relation) self.menuRelations.addAction(self.action_Save_relation) self.menuRelations.addAction(self.actionEdit_relation) self.menuRelations.addAction(self.actionUnload_relation) self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuRelations.menuAction()) self.menubar.addAction(self.menuAbout.menuAction()) self.label.setBuddy(self.txtQuery) self.retranslateUi(MainWindow) QtCore.QObject.connect(self.cmdClearQuery, QtCore.SIGNAL("clicked()"), self.txtQuery.clear) QtCore.QObject.connect(self.cmdClearHistory, QtCore.SIGNAL("clicked()"), self.lstHistory.clear) QtCore.QObject.connect(self.txtQuery, QtCore.SIGNAL("returnPressed()"), MainWindow.execute) QtCore.QObject.connect(self.cmdExecute, QtCore.SIGNAL("clicked()"), MainWindow.execute) QtCore.QObject.connect(self.cmdAbout, QtCore.SIGNAL("clicked()"), MainWindow.showAbout) QtCore.QObject.connect(self.cmdSurvey, QtCore.SIGNAL("clicked()"), MainWindow.showSurvey) QtCore.QObject.connect(self.cmdProduct, QtCore.SIGNAL("clicked()"), MainWindow.addProduct) QtCore.QObject.connect(self.cmdDifference, QtCore.SIGNAL("clicked()"), MainWindow.addDifference) QtCore.QObject.connect(self.cmdArrow, QtCore.SIGNAL("clicked()"), MainWindow.addArrow) QtCore.QObject.connect(self.cmdRename, QtCore.SIGNAL("clicked()"), MainWindow.addRename) QtCore.QObject.connect(self.cmdSelection, QtCore.SIGNAL("clicked()"), MainWindow.addSelection) QtCore.QObject.connect(self.cmdProjection, QtCore.SIGNAL("clicked()"), MainWindow.addProjection) QtCore.QObject.connect(self.cmdUnload, QtCore.SIGNAL("clicked()"), MainWindow.unloadRelation) QtCore.QObject.connect(self.cmdSave, QtCore.SIGNAL("clicked()"), MainWindow.saveRelation) QtCore.QObject.connect(self.cmdLoad, QtCore.SIGNAL("clicked()"), MainWindow.loadRelation) QtCore.QObject.connect(self.cmdOptimize, QtCore.SIGNAL("clicked()"), MainWindow.optimize) QtCore.QObject.connect(self.cmdUndoOptimize, QtCore.SIGNAL("clicked()"), MainWindow.undoOptimize) QtCore.QObject.connect(self.txtResult, QtCore.SIGNAL("returnPressed()"), self.txtQuery.setFocus) QtCore.QObject.connect(self.cmdOuterRight, QtCore.SIGNAL("clicked()"), MainWindow.addORight) QtCore.QObject.connect(self.cmdOuter, QtCore.SIGNAL("clicked()"), MainWindow.addOuter) QtCore.QObject.connect(self.cmdOuterLeft, QtCore.SIGNAL("clicked()"), MainWindow.addOLeft) QtCore.QObject.connect(self.cmdJoin, QtCore.SIGNAL("clicked()"), MainWindow.addJoin) QtCore.QObject.connect(self.cmdDivision, QtCore.SIGNAL("clicked()"), MainWindow.addDivision) QtCore.QObject.connect(self.cmdIntersection, QtCore.SIGNAL("clicked()"), MainWindow.addIntersection) QtCore.QObject.connect(self.cmdUnion, QtCore.SIGNAL("clicked()"), MainWindow.addUnion) QtCore.QObject.connect(self.lstRelations, QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"), MainWindow.printRelation) QtCore.QObject.connect(self.lstRelations, QtCore.SIGNAL("itemClicked(QListWidgetItem*)"), MainWindow.showAttributes) QtCore.QObject.connect(self.cmdClearQuery, QtCore.SIGNAL("clicked()"), self.txtQuery.setFocus) QtCore.QObject.connect(self.lstHistory, QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"), MainWindow.resumeHistory) QtCore.QObject.connect(self.actionAbout, QtCore.SIGNAL("triggered()"), MainWindow.showAbout) QtCore.QObject.connect(self.action_Load_relation, QtCore.SIGNAL("triggered()"), MainWindow.loadRelation) QtCore.QObject.connect(self.action_Save_relation, QtCore.SIGNAL("triggered()"), MainWindow.saveRelation) QtCore.QObject.connect(self.action_Quit, QtCore.SIGNAL("triggered()"), MainWindow.close) QtCore.QObject.connect(self.actionCheck_for_new_versions, QtCore.SIGNAL("triggered()"), MainWindow.checkVersion) QtCore.QObject.connect(self.cmdEdit, QtCore.SIGNAL("clicked()"), MainWindow.editRelation) QtCore.QObject.connect(self.actionEdit_relation, QtCore.SIGNAL("triggered()"), MainWindow.editRelation) QtCore.QObject.connect(self.cmdNew, QtCore.SIGNAL("clicked()"), MainWindow.newRelation) QtCore.QObject.connect(self.actionNew_relation, QtCore.SIGNAL("triggered()"), MainWindow.newRelation) QtCore.QObject.connect(self.actionUnload_relation, QtCore.SIGNAL("triggered()"), MainWindow.unloadRelation) QtCore.QMetaObject.connectSlotsByName(MainWindow) MainWindow.setTabOrder(self.cmdAbout, self.cmdSurvey) MainWindow.setTabOrder(self.cmdSurvey, self.cmdProduct) MainWindow.setTabOrder(self.cmdProduct, self.cmdDifference) MainWindow.setTabOrder(self.cmdDifference, self.cmdUnion) MainWindow.setTabOrder(self.cmdUnion, self.cmdIntersection) MainWindow.setTabOrder(self.cmdIntersection, self.cmdDivision) MainWindow.setTabOrder(self.cmdDivision, self.cmdJoin) MainWindow.setTabOrder(self.cmdJoin, self.cmdOuterLeft) MainWindow.setTabOrder(self.cmdOuterLeft, self.cmdOuterRight) MainWindow.setTabOrder(self.cmdOuterRight, self.cmdOuter) MainWindow.setTabOrder(self.cmdOuter, self.cmdProjection) MainWindow.setTabOrder(self.cmdProjection, self.cmdSelection) MainWindow.setTabOrder(self.cmdSelection, self.cmdRename) MainWindow.setTabOrder(self.cmdRename, self.cmdArrow) MainWindow.setTabOrder(self.cmdArrow, self.table) MainWindow.setTabOrder(self.table, self.lstHistory) MainWindow.setTabOrder(self.lstHistory, self.cmdOptimize) MainWindow.setTabOrder(self.cmdOptimize, self.cmdUndoOptimize) MainWindow.setTabOrder(self.cmdUndoOptimize, self.cmdClearHistory) MainWindow.setTabOrder(self.cmdClearHistory, self.lstRelations) MainWindow.setTabOrder(self.lstRelations, self.cmdLoad) MainWindow.setTabOrder(self.cmdLoad, self.cmdSave) MainWindow.setTabOrder(self.cmdSave, self.cmdUnload) MainWindow.setTabOrder(self.cmdUnload, self.lstAttributes) MainWindow.setTabOrder(self.lstAttributes, self.txtResult) MainWindow.setTabOrder(self.txtResult, self.txtQuery) MainWindow.setTabOrder(self.txtQuery, self.cmdClearQuery) MainWindow.setTabOrder(self.cmdClearQuery, self.cmdExecute) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Relational", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_3.setTitle(QtGui.QApplication.translate("MainWindow", "Menu", None, QtGui.QApplication.UnicodeUTF8)) self.cmdAbout.setText(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)) self.cmdSurvey.setText(QtGui.QApplication.translate("MainWindow", "Survey", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_4.setTitle(QtGui.QApplication.translate("MainWindow", "Operators", None, QtGui.QApplication.UnicodeUTF8)) self.cmdProduct.setToolTip(QtGui.QApplication.translate("MainWindow", "Product", None, QtGui.QApplication.UnicodeUTF8)) self.cmdProduct.setText(QtGui.QApplication.translate("MainWindow", "*", None, QtGui.QApplication.UnicodeUTF8)) self.cmdDifference.setToolTip(QtGui.QApplication.translate("MainWindow", "Difference", None, QtGui.QApplication.UnicodeUTF8)) self.cmdDifference.setText(QtGui.QApplication.translate("MainWindow", "-", None, QtGui.QApplication.UnicodeUTF8)) self.cmdUnion.setToolTip(QtGui.QApplication.translate("MainWindow", "Union", None, QtGui.QApplication.UnicodeUTF8)) self.cmdUnion.setText(QtGui.QApplication.translate("MainWindow", "ᑌ", None, QtGui.QApplication.UnicodeUTF8)) self.cmdIntersection.setToolTip(QtGui.QApplication.translate("MainWindow", "Intersection", None, QtGui.QApplication.UnicodeUTF8)) self.cmdIntersection.setText(QtGui.QApplication.translate("MainWindow", "ᑎ", None, QtGui.QApplication.UnicodeUTF8)) self.cmdDivision.setToolTip(QtGui.QApplication.translate("MainWindow", "Division", None, QtGui.QApplication.UnicodeUTF8)) self.cmdDivision.setText(QtGui.QApplication.translate("MainWindow", "÷", None, QtGui.QApplication.UnicodeUTF8)) self.cmdJoin.setToolTip(QtGui.QApplication.translate("MainWindow", "Natural join", None, QtGui.QApplication.UnicodeUTF8)) self.cmdJoin.setText(QtGui.QApplication.translate("MainWindow", "ᐅᐊ", None, QtGui.QApplication.UnicodeUTF8)) self.cmdOuterLeft.setToolTip(QtGui.QApplication.translate("MainWindow", "Left outer join", None, QtGui.QApplication.UnicodeUTF8)) self.cmdOuterLeft.setText(QtGui.QApplication.translate("MainWindow", "ᐅLEFTᐊ", None, QtGui.QApplication.UnicodeUTF8)) self.cmdOuterRight.setToolTip(QtGui.QApplication.translate("MainWindow", "Right outer join", None, QtGui.QApplication.UnicodeUTF8)) self.cmdOuterRight.setText(QtGui.QApplication.translate("MainWindow", "ᐅRIGHTᐊ", None, QtGui.QApplication.UnicodeUTF8)) self.cmdOuter.setToolTip(QtGui.QApplication.translate("MainWindow", "Full outer join", None, QtGui.QApplication.UnicodeUTF8)) self.cmdOuter.setText(QtGui.QApplication.translate("MainWindow", "ᐅFULLᐊ", None, QtGui.QApplication.UnicodeUTF8)) self.cmdProjection.setToolTip(QtGui.QApplication.translate("MainWindow", "Projection", None, QtGui.QApplication.UnicodeUTF8)) self.cmdProjection.setText(QtGui.QApplication.translate("MainWindow", "π", None, QtGui.QApplication.UnicodeUTF8)) self.cmdSelection.setToolTip(QtGui.QApplication.translate("MainWindow", "Selection", None, QtGui.QApplication.UnicodeUTF8)) self.cmdSelection.setText(QtGui.QApplication.translate("MainWindow", "σ", None, QtGui.QApplication.UnicodeUTF8)) self.cmdRename.setToolTip(QtGui.QApplication.translate("MainWindow", "Rename", None, QtGui.QApplication.UnicodeUTF8)) self.cmdRename.setText(QtGui.QApplication.translate("MainWindow", "ρ", None, QtGui.QApplication.UnicodeUTF8)) self.cmdArrow.setText(QtGui.QApplication.translate("MainWindow", "➡", None, QtGui.QApplication.UnicodeUTF8)) self.cmdOptimize.setText(QtGui.QApplication.translate("MainWindow", "Optimize", None, QtGui.QApplication.UnicodeUTF8)) self.cmdUndoOptimize.setText(QtGui.QApplication.translate("MainWindow", "Undo optimize", None, QtGui.QApplication.UnicodeUTF8)) self.cmdClearHistory.setText(QtGui.QApplication.translate("MainWindow", "Clear history", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox.setTitle(QtGui.QApplication.translate("MainWindow", "Relations", None, QtGui.QApplication.UnicodeUTF8)) self.lstRelations.setSortingEnabled(True) self.cmdNew.setText(QtGui.QApplication.translate("MainWindow", "New relation", None, QtGui.QApplication.UnicodeUTF8)) self.cmdLoad.setText(QtGui.QApplication.translate("MainWindow", "Load relation", None, QtGui.QApplication.UnicodeUTF8)) self.cmdSave.setText(QtGui.QApplication.translate("MainWindow", "Save relation", None, QtGui.QApplication.UnicodeUTF8)) self.cmdEdit.setText(QtGui.QApplication.translate("MainWindow", "Edit relation", None, QtGui.QApplication.UnicodeUTF8)) self.cmdUnload.setText(QtGui.QApplication.translate("MainWindow", "Unload relation", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_2.setTitle(QtGui.QApplication.translate("MainWindow", "Attributes", None, QtGui.QApplication.UnicodeUTF8)) self.txtResult.setText(QtGui.QApplication.translate("MainWindow", "_last1", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate("MainWindow", "=", None, QtGui.QApplication.UnicodeUTF8)) self.cmdClearQuery.setText(QtGui.QApplication.translate("MainWindow", "⌫", None, QtGui.QApplication.UnicodeUTF8)) self.cmdExecute.setText(QtGui.QApplication.translate("MainWindow", "Execute", None, QtGui.QApplication.UnicodeUTF8)) self.menuFile.setTitle(QtGui.QApplication.translate("MainWindow", "&File", None, QtGui.QApplication.UnicodeUTF8)) self.menuAbout.setTitle(QtGui.QApplication.translate("MainWindow", "&Help", None, QtGui.QApplication.UnicodeUTF8)) self.menuRelations.setTitle(QtGui.QApplication.translate("MainWindow", "Relations", None, QtGui.QApplication.UnicodeUTF8)) self.actionAbout.setText(QtGui.QApplication.translate("MainWindow", "&About", None, QtGui.QApplication.UnicodeUTF8)) self.action_Load_relation.setText(QtGui.QApplication.translate("MainWindow", "&Load relation", None, QtGui.QApplication.UnicodeUTF8)) self.action_Load_relation.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+O", None, QtGui.QApplication.UnicodeUTF8)) self.action_Save_relation.setText(QtGui.QApplication.translate("MainWindow", "&Save relation", None, QtGui.QApplication.UnicodeUTF8)) self.action_Save_relation.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+S", None, QtGui.QApplication.UnicodeUTF8)) self.action_Quit.setText(QtGui.QApplication.translate("MainWindow", "&Quit", None, QtGui.QApplication.UnicodeUTF8)) self.action_Quit.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+Q", None, QtGui.QApplication.UnicodeUTF8)) self.actionCheck_for_new_versions.setText(QtGui.QApplication.translate("MainWindow", "Check for new versions", None, QtGui.QApplication.UnicodeUTF8)) self.actionNew_relation.setText(QtGui.QApplication.translate("MainWindow", "New relation", None, QtGui.QApplication.UnicodeUTF8)) self.actionNew_relation.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+N", None, QtGui.QApplication.UnicodeUTF8)) self.actionEdit_relation.setText(QtGui.QApplication.translate("MainWindow", "Edit relation", None, QtGui.QApplication.UnicodeUTF8)) self.actionEdit_relation.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+E", None, QtGui.QApplication.UnicodeUTF8)) self.actionNew_session.setText(QtGui.QApplication.translate("MainWindow", "New session", None, QtGui.QApplication.UnicodeUTF8)) self.actionSave_session_as.setText(QtGui.QApplication.translate("MainWindow", "Save session as", None, QtGui.QApplication.UnicodeUTF8)) self.actionSave_session_as.setToolTip(QtGui.QApplication.translate("MainWindow", "Save session as", None, QtGui.QApplication.UnicodeUTF8)) self.actionManage_sessions.setText(QtGui.QApplication.translate("MainWindow", "Manage sessions", None, QtGui.QApplication.UnicodeUTF8)) self.actionUnload_relation.setText(QtGui.QApplication.translate("MainWindow", "Unload relation", None, QtGui.QApplication.UnicodeUTF8)) relational/relational_readline/0000755000175100017510000000000012257142102016235 5ustar salvosalvorelational/relational_readline/linegui.py0000644000175100017510000002420512257142102020246 0ustar salvosalvo# -*- coding: utf-8 -*- # coding=UTF-8 # Relational # Copyright (C) 2010 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # Initial readline code from # http://www.doughellmann.com/PyMOTW/readline/index.html import readline import logging import os.path import os import sys from relational import relation, parser, rtypes from xtermcolor import colorize PROMPT_COLOR = 0xffff00 ERROR_COLOR = 0xff0000 class SimpleCompleter(object): '''Handles completion''' def __init__(self, options): '''Takes a list of valid completion options''' self.options = sorted(options) return def add_completion(self, option): '''Adds one string to the list of the valid completion options''' if option not in self.options: self.options.append(option) self.options.sort() def remove_completion(self, option): '''Removes one completion from the list of the valid completion options''' if option in self.options: self.options.remove(option) pass def complete(self, text, state): response = None if state == 0: # This is the first time for this text, so build a match list. if text: self.matches = [s for s in self.options if s and s.startswith(text)] # Add the completion for files here try: d = os.path.dirname(text) listf = os.listdir(d) d += "/" except: d = "" listf = os.listdir('.') for i in listf: i = (d + i).replace('//', '/') if i.startswith(text): if os.path.isdir(i): i = i + "/" self.matches.append(i) logging.debug('%s matches: %s', repr(text), self.matches) else: self.matches = self.options[:] logging.debug('(empty input) matches: %s', self.matches) # Return the state'th item from the match list, # if we have that many. try: response = self.matches[state] except IndexError: response = None logging.debug('complete(%s, %s) => %s', repr(text), state, repr(response)) return response relations = {} completer = SimpleCompleter( ['SURVEY', 'LIST', 'LOAD ', 'UNLOAD ', 'HELP ', 'QUIT', 'SAVE ', '_PRODUCT ', '_UNION ', '_INTERSECTION ', '_DIFFERENCE ', '_JOIN ', '_LJOIN ', '_RJOIN ', '_FJOIN ', '_PROJECTION ', '_RENAME_TO ', '_SELECTION ', '_RENAME ', '_DIVISION ']) def load_relation(filename, defname=None): if not os.path.isfile(filename): print >> sys.stderr, colorize( "%s is not a file" % filename, ERROR_COLOR) return None f = filename.split('/') if defname == None: defname = f[len(f) - 1].lower() if defname.endswith(".csv"): # removes the extension defname = defname[:-4] if not rtypes.is_valid_relation_name(defname): print >> sys.stderr, colorize( "%s is not a valid relation name" % defname, ERROR_COLOR) return try: relations[defname] = relation.relation(filename) completer.add_completion(defname) print colorize("Loaded relation %s" % defname, 0x00ff00) return defname except Exception, e: print >>sys.stderr, colorize(e, ERROR_COLOR) return None def survey(): '''performs a survey''' from relational import maintenance post = {'software': 'Relational algebra (cli)', 'version': version} fields = ('System', 'Country', 'School', 'Age', 'How did you find', 'email (only if you want a reply)', 'Comments') for i in fields: a = raw_input('%s: ' % i) post[i] = a maintenance.send_survey(post) def help(command): '''Prints help on the various functions''' p = command.split(' ', 1) if len(p) == 1: print 'HELP command' print 'To execute a query:\n[relation =] query\nIf the 1st part is omitted, the result will be stored in the relation last_.' print 'To prevent from printing the relation, append a ; to the end of the query.' print 'To insert relational operators, type _OPNAME, they will be internally replaced with the correct symbol.' print 'Rember: the tab key is enabled and can be very helpful if you can\'t remember something.' return cmd = p[1] if cmd == 'QUIT': print 'Quits the program' elif cmd == 'LIST': print "Lists the relations loaded" elif cmd == 'LOAD': print "LOAD filename [relationame]" print "Loads a relation into memory" elif cmd == 'UNLOAD': print "UNLOAD relationame" print "Unloads a relation from memory" elif cmd == 'SAVE': print "SAVE filename relationame" print "Saves a relation in a file" elif cmd == 'HELP': print "Prints the help on a command" elif cmd == 'SURVEY': print "Fill and send a survey" else: print "Unknown command: %s" % cmd def exec_line(command): command = command.strip() if command.startswith(';'): return elif command == 'QUIT': sys.exit(0) elif command.startswith('HELP'): help(command) elif command == 'LIST': # Lists all the loaded relations for i in relations: if not i.startswith('_'): print i elif command == 'SURVEY': survey() elif command.startswith('LOAD '): # Loads a relation pars = command.split(' ') if len(pars) == 1: print colorize("Missing parameter", ERROR_COLOR) return filename = pars[1] if len(pars) > 2: defname = pars[2] else: defname = None load_relation(filename, defname) elif command.startswith('UNLOAD '): pars = command.split(' ') if len(pars) < 2: print colorize("Missing parameter", ERROR_COLOR) return if pars[1] in relations: del relations[pars[1]] completer.remove_completion(pars[1]) else: print colorize("No such relation %s" % pars[1], ERROR_COLOR) pass elif command.startswith('SAVE '): pars = command.split(' ') if len(pars) != 3: print colorize("Missing parameter", ERROR_COLOR) return filename = pars[1] defname = pars[2] if defname not in relations: print colorize("No such relation %s" % defname, ERROR_COLOR) return try: relations[defname].save(filename) except Exception, e: print colorize(e, ERROR_COLOR) else: exec_query(command) def replacements(query): '''This funcion replaces ascii easy operators with the correct ones''' query = query.replace(u'_PRODUCT', u'*') query = query.replace(u'_UNION', u'ᑌ') query = query.replace(u'_INTERSECTION', u'ᑎ') query = query.replace(u'_DIFFERENCE', u'-') query = query.replace(u'_JOIN', u'ᐅᐊ') query = query.replace(u'_LJOIN', u'ᐅLEFTᐊ') query = query.replace(u'_RJOIN', u'ᐅRIGHTᐊ') query = query.replace(u'_FJOIN', u'ᐅFULLᐊ') query = query.replace(u'_PROJECTION', u'π') query = query.replace(u'_RENAME_TO', u'➡') query = query.replace(u'_SELECTION', u'σ') query = query.replace(u'_RENAME', u'ρ') query = query.replace(u'_DIVISION', u'÷') return query def exec_query(command): '''This function executes a query and prints the result on the screen if the command terminates with ";" the result will not be printed ''' command = unicode(command, 'utf-8') # If it terminates with ; doesn't print the result if command.endswith(';'): command = command[:-1] printrel = False else: printrel = True # Performs replacements for weird operators command = replacements(command) # Finds the name in where to save the query parts = command.split('=', 1) if len(parts) > 1 and rtypes.is_valid_relation_name(parts[0]): relname = parts[0] query = parts[1] else: relname = 'last_' query = command # Execute query try: pyquery = parser.parse(query) result = eval(pyquery, relations) print colorize("-> query: %s" % pyquery.encode('utf-8'), 0x00ff00) if printrel: print print result relations[relname] = result completer.add_completion(relname) except Exception, e: print colorize(e, ERROR_COLOR) def main(files=[]): print colorize('> ', PROMPT_COLOR) + "; Type HELP to get the HELP" print colorize('> ', PROMPT_COLOR) + "; Completion is activated using the tab (if supported by the terminal)" for i in files: load_relation(i) readline.set_completer(completer.complete) readline.parse_and_bind('tab: complete') readline.parse_and_bind('set editing-mode emacs') readline.set_completer_delims(" ") while True: try: line = raw_input(colorize('> ', PROMPT_COLOR)) if isinstance(line, str) and len(line) > 0: exec_line(line) except KeyboardInterrupt: print continue except EOFError: print sys.exit(0) if __name__ == "__main__": main() relational/relational_readline/__init__.py0000644000175100017510000000000012257142102020334 0ustar salvosalvorelational/Makefile0000644000175100017510000000535412257142102013707 0ustar salvosalvodefault: echo "sorry, no default action" gui: pyqt pyside pyside: pyside-uic relational_pyside/survey.ui > relational_pyside/survey.py pyside-uic relational_pyside/maingui.ui > relational_pyside/maingui.py pyside-uic relational_pyside/rel_edit.ui > relational_pyside/rel_edit.py pyqt: pyuic4 relational_gui/survey.ui > relational_gui/survey.py pyuic4 relational_gui/maingui.ui > relational_gui/maingui.py pyuic4 relational_gui/rel_edit.ui > relational_gui/rel_edit.py uninstall: rm -rf /opt/relational rm -f /usr/local/bin/relational rm -f /usr/share/applications/relational.desktop install: mkdir /opt/relational cp -R relational relational_gui /opt/relational/ cp relational_gui.py /opt/relational chmod -R 555 /opt/relational/ echo "#!/bin/bash" > /usr/local/bin/relational echo "/opt/relational/relational_gui.py" >> /usr/local/bin/relational chmod 555 /usr/local/bin/relational cp relational.desktop /usr/share/applications/ chmod a+r /usr/share/applications/relational.desktop dist: clean rm -rf /tmp/relational/ rm -rf /tmp/relational-* mkdir /tmp/relational/ cp -R * /tmp/relational/ rm -rf /tmp/relational/windows rm -rf /tmp/relational/samples/.svn/ rm -rf /tmp/relational/setup/.svn/ rm -rf /tmp/relational/debscript/.svn/ rm -rf /tmp/relational/mac/.svn/ rm -rf /tmp/relational/relational/.svn/ rm -rf /tmp/relational/relational_gui/.svn/ rm -rf /tmp/relational/relational_pyside/.svn/ rm -rf /tmp/relational/mac rm -rf /tmp/relational/debian/ rm -rf /tmp/relational/relational_curses/.svn/ rm -rf /tmp/relational/relational_readline/.svn/ rm -rf /tmp/relational/test/.svn #mv /tmp/relational /tmp/relational-`./relational_gui.py -v | grep Relational | cut -d" " -f2` #(cd /tmp; tar -zcf relational.tar.gz relational-*/) (cd /tmp; tar -zcf relational.tar.gz relational/) mv /tmp/relational.tar.gz ./relational_`./relational_gui.py -v | grep Relational | cut -d" " -f2`.orig.tar.gz clean: rm -rf *~ || echo ok rm -rf *.pyc *.pyo || echo ok rm -rf Relational.app || echo ok rm relational*.tar.gz || echo ok rm -rf relational_mac rm -rf data || echo ok rm -rf *tar.bz || echo ok rm -rf *.deb || echo ok rm -rf relational/*~ || echo ok rm -rf relational/*.pyc relational/*.pyo || echo ok rm -rf relational_gui/*~ || echo ok rm -rf relational_gui/*.pyc || echo ok rm -rf relational_gui/*.pyo || echo ok rm -rf relational_curses/*~ || echo ok rm -rf relational_curses/*.pyc || echo ok rm -rf relational_curses/*.pyo || echo ok rm -rf relational_readline/*~ || echo ok rm -rf relational_readline/*.pyc || echo ok rm -rf relational_readline/*.pyo || echo ok rm -rf setup/*~ || echo ok rm -rf setup/*.pyc || echo ok rm -rf setup/*.pyo || echo ok rm -rf relational_mac rm -rf test/*~ debian: dpkg-buildpackage relational/feedback-ltworf/0000755000175100017510000000000012257142102015277 5ustar salvosalvorelational/feedback-ltworf/app.yaml0000644000175100017510000000021712257142102016743 0ustar salvosalvoapplication: feedback-ltworf version: 1 runtime: python27 api_version: 3 threadsafe: true handlers: - url: /.* script: feedback.application relational/feedback-ltworf/feedback.pyc0000644000175100017510000000226212257142102017542 0ustar salvosalvo Rc@shddlmZddlZddlZejZejddZejddZdS(i(tusersNt/cOsdS(Nt((trequesttargstkwargs((s6/home/salvo/dev/relational/feedback-ltworf/feedback.pytmss/feedback/c Os|jdkrdSd}x1|jjD] \}}|d||f7}q)W|ddkrddlm}|jdd d d d d |dd|ndS(NtPOSTRs%s: %s tidt relationali(tmailtsenders&Feedback service ttostiposchi@tiscali.ittsubjectsFeedback from %stbodysMessage queued(tmethodRt iteritemstgoogle.appengine.apiR t send_mail(RRRtmessagetktvR ((s6/home/salvo/dev/relational/feedback-ltworf/feedback.pyt mail_sender s ( RRtwebapp2t micro_webapp2tWSGIApplicationt applicationtrouteRR(((s6/home/salvo/dev/relational/feedback-ltworf/feedback.pyts    relational/feedback-ltworf/micro_webapp2.pyc0000644000175100017510000000276312257142102020555 0ustar salvosalvo utRc@s)ddlZdejfdYZdS(iNtWSGIApplicationcBs)eZdZedZdZRS(cOs3tt|j|||jj|jjdS(N(tsuperRt__init__troutertset_dispatchert __class__tcustom_dispatcher(tselftargstkwargs((s8/home/salvo/dev/lt-worf/feedback-ltworf/micro_webapp2.pyRscCsX|j||}t|tr3tj|}n!t|trTtj|}n|S(N(tdefault_dispatchert isinstancet basestringtwebapp2tResponsettuple(Rtrequesttresponsetrv((s8/home/salvo/dev/lt-worf/feedback-ltworf/micro_webapp2.pyRs csfd}|S(Ncs&jjtjd||S(Nthandler(RtaddR tRoute(tfunc(RR R(s8/home/salvo/dev/lt-worf/feedback-ltworf/micro_webapp2.pytwrappers"((RRR R((RR Rs8/home/salvo/dev/lt-worf/feedback-ltworf/micro_webapp2.pytroutes(t__name__t __module__Rt staticmethodRR(((s8/home/salvo/dev/lt-worf/feedback-ltworf/micro_webapp2.pyRs  (R R(((s8/home/salvo/dev/lt-worf/feedback-ltworf/micro_webapp2.pyts relational/feedback-ltworf/feedback.py0000644000175100017510000000160112257142102017373 0ustar salvosalvofrom google.appengine.api import users import webapp2 import micro_webapp2 application = micro_webapp2.WSGIApplication() @application.route('/') def m(request, *args, **kwargs): return "" @application.route("/version/") def show_version(request, *args, **kwargs): if kwargs["id"] == "relational": return "1.2" return "No version" @application.route('/feedback/') def mail_sender(request, *args, **kwargs): if request.method != "POST": return "" message = "" for k,v in request.POST.iteritems(): message += "%s: %s\n" % (k,v) if kwargs["id"] == "relational": from google.appengine.api import mail mail.send_mail(sender="Feedback service ", to="tiposchi@tiscali.it", subject="Feedback from %s" % kwargs["id"], body=message) return "Message queued" relational/feedback-ltworf/micro_webapp2.py0000644000175100017510000000132712257142102020405 0ustar salvosalvoimport webapp2 class WSGIApplication(webapp2.WSGIApplication): def __init__(self, *args, **kwargs): super(WSGIApplication, self).__init__(*args, **kwargs) self.router.set_dispatcher(self.__class__.custom_dispatcher) @staticmethod def custom_dispatcher(router, request, response): rv = router.default_dispatcher(request, response) if isinstance(rv, basestring): rv = webapp2.Response(rv) elif isinstance(rv, tuple): rv = webapp2.Response(*rv) return rv def route(self, *args, **kwargs): def wrapper(func): self.router.add(webapp2.Route(handler=func, *args, **kwargs)) return func return wrapper relational/relational_curses/0000755000175100017510000000000012257142102015756 5ustar salvosalvorelational/relational_curses/__init__.py0000644000175100017510000000000012257142102020055 0ustar salvosalvorelational/relational_curses/maingui.py0000644000175100017510000001060612257142102017764 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2010 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli import curses import curses.panel import locale import signal import sys from relational import * def terminate(*a): '''Restores the terminal and terminates''' curses.nocbreak() stdscr.keypad(0) curses.echo() curses.endwin() sys.exit(0) def main(): global stdscr # Initializes the signal signal.signal(signal.SIGINT, terminate) # Initialize locale, to print unicode chars locale.setlocale(locale.LC_ALL, "") # Initializes curses stdscr = curses.initscr() curses.start_color() curses.noecho() curses.cbreak() # Handles keys immediately rather than awaiting for enter stdscr.keypad(1) termsize = stdscr.getmaxyx() symselect = init_symbol_list(termsize) lop = curses.panel.new_panel(stdscr) win = curses.panel.new_panel(curses.newwin(termsize[0], termsize[1])) # win.window().box() win.window().addstr(0, (termsize[1] / 2) - 5, "Relational") win.window().refresh() # curses.napms(1000) query = curses.panel.new_panel(curses.newwin(3, termsize[1], 1, 0)) query.window().box() query.window().addstr(1, 1, "") query.window().refresh() # curses.napms(1000) # win.show() # curses.napms(1000) # qq=curses.textpad.Textbox(stdscr) '''win = curses.newwin(0, 0)#New windows for the entire screen #stdscr.border(0) stdscr.addstr(str(dir (win))) #curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) #stdscr.addstr(0,0,"ciao",curses.color_pair(1)) stdscr.addstr(5, 30, "Welcome to Relational")#,curses.A_REVERSE) stdscr.refresh() stdscr.refresh() curses.napms(300) curses.flash() curses.textpad.rectangle(win,0,0,5,10)''' squery = '' while True: c = win.window().getch() if c == 27: # Escape squery += add_symbol(symselect) # elif c==curses.KEY_BACKSPACE: #Delete elif c == 13: squery = squery[:-1] else: squery += chr(c) query.window().box() query.top() query.window().addstr(1, 1, spaces(termsize[1] - 2)) query.window().addstr(1, 1, squery) query.window().refresh() def init_symbol_list(termsize, create=True): if create: p = curses.panel.new_panel( curses.newwin(15, 16, 2, termsize[1] / 2 - 7)) else: p = termsize p.window().box() # p.window().addstr(1,1,"\n8 \na \nb \n") p.window().addstr(01, 2, "0 *") p.window().addstr(02, 2, "1 -") p.window().addstr(03, 2, "2 ᑌ") p.window().addstr(04, 2, "3 ᑎ") p.window().addstr(05, 2, "4 ᐅᐊ") p.window().addstr(06, 2, "5 ᐅLEFTᐊ") p.window().addstr(07, 2, "6 ᐅRIGHTᐊ") p.window().addstr(8, 2, "7 ᐅFULLᐊ") p.window().addstr(9, 2, "8 σ") p.window().addstr(10, 2, "9 ρ") p.window().addstr(11, 2, "a π") p.window().addstr(12, 2, "b ➡") p.window().addstr(13, 2, "") # p.hide() return p def add_symbol(p): '''Shows the panel to add a symbol and then returns the choosen symbol itself''' init_symbol_list(p, False) d_ = {'0': '*', '1': '-', '2': 'ᑌ', '3': 'ᑎ', '4': 'ᐅᐊ', '5': 'ᐅLEFTᐊ', '6': 'ᐅRIGHTᐊ', '7': 'ᐅFULLᐊ', '8': 'σ', '9': 'ρ', 'a': 'π', 'b': '➡'} p.show() p.top() p.window().refresh() c = p.window().getch() p.hide() p.window().refresh() try: char = d_[chr(c)] except: char = '' return char def spaces(t): '''Returns a number of spaces specified t''' s = '' for i in range(t): s += ' ' return s if __name__ == '__main__': main() terminate() relational/relational.desktop0000644000175100017510000000053412257142102015767 0ustar salvosalvo[Desktop Entry] Name=Relational GenericName=Relational Algebra GenericName[it]=Algebra Relazionale Comment=Learn and experiment relational algebra Comment[it]=Impara l'algebra relazionale Exec=relational Icon=kexi Terminal=0 Type=Application Categories=Education; Keywords=database;relational;algebra;educational;learn;educativo;relazionale;impara relational/relational-cli.10000644000175100017510000000211712257142102015222 0ustar salvosalvo.TH "Relational" "1" .SH "NAME" relational-cli \(em Python implementation of Relational algebra. .SH "SYNOPSIS" .PP \fBrelational\fR [OPTIONS\fR\fP] [ FILE .\|.\|.] .SH "DESCRIPTION" .PP Python implementation of Relational algebra. This program provides a command line interface to execute relational algebra queries. It is meant to be used for educational purposes. .SH "OPTIONS" .PP These programs follow the usual GNU command line syntax, with long options starting with two dashes (`\-'). A summary of options is included below. However, the ordering is very strict \- .IP "\fB-v\fP Show version information. .IP "\fB-h\fP Shows help. .IP "\fB-q\fP Uses the Qt4 GUI. .IP "\fB-r\fP Uses the readline UI (default). .SH "AUTHOR" .PP This manual page was written by Salvo 'LtWorf' Tomaselli for the \fBDebian GNU/Linux\fP system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License version 3 or any later version published by the Free Software Foundation. relational/relational/0000755000175100017510000000000012257142102014372 5ustar salvosalvorelational/relational/maintenance.py0000644000175100017510000000546212257142102017235 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relation is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # Stuff non-related to relational algebra, but used for maintenance. import httplib import urllib import relation def send_survey(data): '''Sends the survey. Data must be a dictionary. returns the http response''' post = '' for i in data.keys(): post += '%s: %s\n' % (i, data[i]) # sends the string params = urllib.urlencode({'survey': post}) headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} connection = httplib.HTTPConnection('feedback-ltworf.appspot.com') connection.request("POST", "/feedback/relational", params, headers) return connection.getresponse() def check_latest_version(): '''Returns the latest version available. Heavely dependent on server and server configurations not granted to work forever.''' connection = httplib.HTTPConnection('feedback-ltworf.appspot.com') connection.request("GET", "/version/relational") r = connection.getresponse() # html s = r.read() if len(s) == 0: return None return s.strip() class interface (object): '''It is used to provide services to the user interfaces, in order to reduce the amount of duplicated code present in different user interfaces. ''' def __init__(self): self.rels = {} def load(self, filename, name): '''Loads a relation from file, and gives it a name to be used in subsequent queries.''' pass def unload(self, name): '''Unloads an existing relation.''' pass def store(self, filename, name): '''Stores a relation to file.''' pass def get_relation(self, name): '''Returns the relation corresponding to name.''' pass def set_relation(self, name, rel): '''Sets the relation corresponding to name.''' pass def execute(self, query, relname='last_'): '''Executes a query, returns the result and if relname is not None, adds the result to the dictionary, with the name given in relname.''' pass relational/relational/relation.py0000644000175100017510000005132412257142102016566 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # This module provides a classes to represent relations and to perform # relational operations on them. from rtypes import * import csv class relation (object): '''This objects defines a relation (as a group of consistent tuples) and operations A relation can be represented using a table Calling an operation and providing a non relation parameter when it is expected will result in a None value''' __hash__ = None def __init__(self, filename=""): '''Creates a relation, accepts a filename and then it will load the relation from that file. If no parameter is supplied an empty relation is created. Empty relations are used in internal operations. By default the file will be handled like a comma separated as described in RFC4180.''' self._readonly = False if len(filename) == 0: # Empty relation self.content = set() self.header = header([]) return # Opening file fp = file(filename) reader = csv.reader(fp) # Creating a csv reader self.header = header(reader.next()) # read 1st line self.content = set() for i in reader.__iter__(): # Iterating rows self.content.add(tuple(i)) # Closing file fp.close() def _make_writable(self): '''If this relation is marked as readonly, this method will copy the content to make it writable too''' if self._readonly: self.content = set(self.content) self._readonly = False def save(self, filename): '''Saves the relation in a file. By default will save using the csv format as defined in RFC4180, but setting comma_separated to False, it will use the old format with space separated values. ''' fp = file(filename, 'w') # Opening file in write mode writer = csv.writer(fp) # Creating csv writer # It wants an iterable containing iterables head = (self.header.attributes,) writer.writerows(head) # Writing content, already in the correct format writer.writerows(self.content) fp.close() # Closing file def _rearrange_(self, other): '''If two relations share the same attributes in a different order, this method will use projection to make them have the same attributes' order. It is not exactely related to relational algebra. Just a method used internally. Will return None if they don't share the same attributes''' if (self.__class__ != other.__class__): return None if self.header.sharedAttributes(other.header) == len(self.header.attributes) == len(other.header.attributes): return other.projection(list(self.header.attributes)) return None def _autocast(self, string): '''Depending on the regexp matched by the string, it will perform automatic casting''' tmpstring = rstring(string) if len(tmpstring) > 0 and tmpstring.isInt(): return int(tmpstring) elif len(tmpstring) > 0 and tmpstring.isFloat(): return float(tmpstring) elif len(tmpstring) > 0 and tmpstring.isDate(): return rdate(tmpstring) else: return tmpstring def selection(self, expr): '''Selection, expr must be a valid boolean expression, can contain field names, constant, math operations and boolean ones.''' attributes = {} newt = relation() newt.header = header(list(self.header.attributes)) for i in self.content: # Fills the attributes dictionary with the values of the tuple for j in range(len(self.header.attributes)): attributes[self.header.attributes[j]] = self._autocast(i[j]) try: if eval(expr, attributes): newt.content.add(i) except Exception, e: raise Exception( "Failed to evaluate %s\n%s" % (expr, e.__str__())) return newt def product(self, other): '''Cartesian product, attributes must be different to avoid collisions Doing this operation on relations with colliding attributes will cause an exception. It is possible to use rename on attributes and then use the product''' if (self.__class__ != other.__class__)or(self.header.sharedAttributes(other.header) != 0): raise Exception( 'Unable to perform product on relations with colliding attributes') newt = relation() newt.header = header(self.header.attributes + other.header.attributes) for i in self.content: for j in other.content: newt.content.add(i + j) return newt def projection(self, * attributes): '''Projection operator, takes many parameters, for each field to use. Can also use a single parameter with a list. Will delete duplicate items If an empty list or no parameters are provided, returns None''' # Parameters are supplied in a list, instead with multiple parameters if isinstance(attributes[0], list): attributes = attributes[0] # Avoiding duplicated attributes attributes1 = [] for i in attributes: if i not in attributes1: attributes1.append(i) attributes = attributes1 ids = self.header.getAttributesId(attributes) if len(ids) == 0 or len(ids) != len(attributes): raise Exception('Invalid attributes for projection') newt = relation() # Create the header h = [] for i in ids: h.append(self.header.attributes[i]) newt.header = header(h) # Create the body for i in self.content: row = [] for j in ids: row.append(i[j]) newt.content.add(tuple(row)) return newt def rename(self, params): '''Operation rename. Takes a dictionary Will replace the itmem with its content. For example if you want to rename a to b, provide {"a":"b"} ''' result = [] newt = relation() newt.header = header(list(self.header.attributes)) for old, new in params.iteritems(): if (newt.header.rename(old, new)) == False: raise Exception('Unable to find attribute: %s' % old) newt.content = self.content newt._readonly = True return newt def intersection(self, other): '''Intersection operation. The result will contain items present in both operands. Will return an empty one if there are no common items. Will return None if headers are different. It is possible to use projection and rename to make headers match.''' other = self._rearrange_(other) # Rearranges attributes' order if (self.__class__ != other.__class__)or(self.header != other.header): raise Exception( 'Unable to perform intersection on relations with different attributes') newt = relation() newt.header = header(list(self.header.attributes)) newt.content = self.content.intersection(other.content) return newt def difference(self, other): '''Difference operation. The result will contain items present in first operand but not in second one. Will return an empty one if the second is a superset of first. Will return None if headers are different. It is possible to use projection and rename to make headers match.''' other = self._rearrange_(other) # Rearranges attributes' order if (self.__class__ != other.__class__)or(self.header != other.header): raise Exception( 'Unable to perform difference on relations with different attributes') newt = relation() newt.header = header(list(self.header.attributes)) newt.content = self.content.difference(other.content) return newt def division(self, other): '''Division operator The division is a binary operation that is written as R ÷ S. The result consists of the restrictions of tuples in R to the attribute names unique to R, i.e., in the header of R but not in the header of S, for which it holds that all their combinations with tuples in S are present in R. ''' # d_headers are the headers from self that aren't also headers in other d_headers = list( set(self.header.attributes) - set(other.header.attributes)) ''' Wikipedia defines the division as follows: a1,....,an are the d_headers T := πa1,...,an(R) × S U := T - R V := πa1,...,an(U) W := πa1,...,an(R) - V W is the result that we want ''' t = self.projection(d_headers).product(other) return self.projection(d_headers).difference(t.difference(self).projection(d_headers)) def union(self, other): '''Union operation. The result will contain items present in first and second operands. Will return an empty one if both are empty. Will not insert tuplicated items. Will return None if headers are different. It is possible to use projection and rename to make headers match.''' other = self._rearrange_(other) # Rearranges attributes' order if (self.__class__ != other.__class__)or(self.header != other.header): raise Exception( 'Unable to perform union on relations with different attributes') newt = relation() newt.header = header(list(self.header.attributes)) newt.content = self.content.union(other.content) return newt def thetajoin(self, other, expr): '''Defined as product and then selection with the given expression.''' return self.product(other).selection(expr) def outer(self, other): '''Does a left and a right outer join and returns their union.''' a = self.outer_right(other) b = self.outer_left(other) return a.union(b) def outer_right(self, other): '''Outer right join. Considers self as left and param as right. If the tuple has no corrispondence, empy attributes are filled with a "---" string. This is due to the fact that empty string or a space would cause problems when saving the relation. Just like natural join, it works considering shared attributes.''' return other.outer_left(self) def outer_left(self, other, swap=False): '''Outer left join. Considers self as left and param as right. If the tuple has no corrispondence, empty attributes are filled with a "---" string. This is due to the fact that empty string or a space would cause problems when saving the relation. Just like natural join, it works considering shared attributes.''' shared = [] for i in self.header.attributes: if i in other.header.attributes: shared.append(i) newt = relation() # Creates the new relation # Adds all the attributes of the 1st relation newt.header = header(list(self.header.attributes)) # Adds all the attributes of the 2nd, when non shared for i in other.header.attributes: if i not in shared: newt.header.attributes.append(i) # Shared ids of self sid = self.header.getAttributesId(shared) # Shared ids of the other relation oid = other.header.getAttributesId(shared) # Non shared ids of the other relation noid = [] for i in range(len(other.header.attributes)): if i not in oid: noid.append(i) for i in self.content: # Tuple partecipated to the join? added = False for j in other.content: match = True for k in range(len(sid)): match = match and (i[sid[k]] == j[oid[k]]) if match: item = list(i) for l in noid: item.append(j[l]) newt.content.add(tuple(item)) added = True # If it didn't partecipate, adds it if not added: item = list(i) for l in range(len(noid)): item.append("---") newt.content.add(tuple(item)) return newt def join(self, other): '''Natural join, joins on shared attributes (one or more). If there are no shared attributes, it will behave as cartesian product.''' # List of attributes in common between the relations shared = list(set(self.header.attributes) .intersection(set(other.header.attributes))) newt = relation() # Creates the new relation # Adding to the headers all the fields, done like that because order is # needed newt.header = header(list(self.header.attributes)) for i in other.header.attributes: if i not in shared: newt.header.attributes.append(i) # Shared ids of self sid = self.header.getAttributesId(shared) # Shared ids of the other relation oid = other.header.getAttributesId(shared) # Non shared ids of the other relation noid = [] for i in range(len(other.header.attributes)): if i not in oid: noid.append(i) for i in self.content: for j in other.content: match = True for k in range(len(sid)): match = match and (i[sid[k]] == j[oid[k]]) if match: item = list(i) for l in noid: item.append(j[l]) newt.content.add(tuple(item)) return newt def __eq__(self, other): '''Returns true if the relations are the same, ignoring order of items. This operation is rather heavy, since it requires sorting and comparing.''' other = self._rearrange_( other) # Rearranges attributes' order so can compare tuples directly if (self.__class__ != other.__class__)or(self.header != other.header): return False # Both parameters must be a relation if set(self.header.attributes) != set(other.header.attributes): return False # comparing content return self.content == other.content def __str__(self): '''Returns a string representation of the relation, can be printed with monospaced fonts''' m_len = [] # Maximum lenght string for f in self.header.attributes: m_len.append(len(f)) for f in self.content: col = 0 for i in f: if len(i) > m_len[col]: m_len[col] = len(i) col += 1 res = "" for f in range(len(self.header.attributes)): res += "%s" % (self.header.attributes[f].ljust(2 + m_len[f])) for r in self.content: col = 0 res += "\n" for i in r: res += "%s" % (i.ljust(2 + m_len[col])) col += 1 return res def update(self, expr, dic): '''Update, expr must be a valid boolean expression, can contain field names, constant, math operations and boolean ones. This operation will change the relation itself instead of generating a new one, updating all the tuples that make expr true. Dic must be a dictionary that has the form field name:value. Every kind of value will be converted into a string. Returns the number of affected rows.''' self._make_writable() affected = 0 attributes = {} keys = dic.keys() # List of headers to modify f_ids = self.header.getAttributesId( keys) # List of indexes corresponding to keys # new_content=[] #New content of the relation for i in self.content: for j in range(len(self.header.attributes)): attributes[self.header.attributes[j]] = self._autocast(i[j]) if eval(expr, attributes): # If expr is true, changing the tuple affected += 1 new_tuple = list(i) # Deleting the tuple, instead of changing it, so other # relations can still point to the same list without # being affected. self.content.remove(i) for k in range(len(keys)): new_tuple[f_ids[k]] = str(dic[keys[k]]) self.content.add(tuple(new_tuple)) return affected def insert(self, values): '''Inserts a tuple in the relation. This function will not insert duplicate tuples. All the values will be converted in string. Will return the number of inserted rows.''' # Returns if tuple doesn't fit the number of attributes if len(self.header.attributes) != len(values): return 0 self._make_writable() # Creating list containing only strings t = [] for i in values: t.append(str(i)) prevlen = len(self.content) self.content.add(tuple(t)) return len(self.content) - prevlen def delete(self, expr): '''Delete, expr must be a valid boolean expression, can contain field names, constant, math operations and boolean ones. This operation will change the relation itself instead of generating a new one, deleting all the tuples that make expr true. Returns the number of affected rows.''' self._make_writable() attributes = {} affected = len(self.content) new_content = set() # New content of the relation for i in self.content: for j in range(len(self.header.attributes)): attributes[self.header.attributes[j]] = self._autocast(i[j]) if not eval(expr, attributes): affected -= 1 new_content.add(i) self.content = new_content return affected class header (object): '''This class defines the header of a relation. It is used within relations to know if requested operations are accepted''' # Since relations are mutalbe we explicitly block hashing them __hash__ = None def __init__(self, attributes): '''Accepts a list with attributes' names. Names MUST be unique''' self.attributes = attributes for i in attributes: if not is_valid_relation_name(i): raise Exception('"%s" is not a valid attribute name' % i) def __repr__(self): return "header(%s)" % (self.attributes.__repr__()) def rename(self, old, new): '''Renames a field. Doesn't check if it is a duplicate. Returns True if the field was renamed, False otherwise''' if not is_valid_relation_name(new): raise Exception('%s is not a valid attribute name' % new) try: id_ = self.attributes.index(old) self.attributes[id_] = new except: return False return True def sharedAttributes(self, other): '''Returns how many attributes this header has in common with a given one''' return len(set(self.attributes).intersection(set(other.attributes))) def __str__(self): '''Returns String representation of the field's list''' return self.attributes.__str__() def __eq__(self, other): return self.attributes == other.attributes def __ne__(self, other): return self.attributes != other.attributes def getAttributesId(self, param): '''Returns a list with numeric index corresponding to field's name''' res = [] for i in param: for j in range(len(self.attributes)): if i == self.attributes[j]: res.append(j) return res relational/relational/optimizer.py0000644000175100017510000001316212257142102016771 0ustar salvosalvo# -*- coding: utf-8 -*- # coding=UTF-8 # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # This module optimizes relational expressions into ones that require less time to be executed. # # expression: In all the functions expression can be either an UTF-8 encoded string, containing a valid # relational query, or it can be a parse tree for a relational expression (ie: class parser.node). # The functions will always return a string with the optimized query, but if a parse tree was provided, # the parse tree itself will be modified accordingly. import optimizations import parser # Stuff that was here before, keeping it for compatibility RELATION = parser.RELATION UNARY = parser.UNARY BINARY = parser.BINARY b_operators = parser.b_operators u_operators = parser.u_operators op_functions = parser.op_functions node = parser.node tokenize = parser.tokenize tree = parser.tree # End of the stuff def optimize_all(expression, rels, specific=True, general=True, debug=None): '''This function performs all the available optimizations. expression : see documentation of this module rels: dic with relation name as key, and relation istance as value specific: True if it has to perform specific optimizations general: True if it has to perform general optimizations debug: if a list is provided here, after the end of the function, it will contain the query repeated many times to show the performed steps. Return value: this will return an optimized version of the expression''' if isinstance(expression, unicode): n = tree(expression) # Gets the tree elif isinstance(expression, node): n = expression else: raise (TypeError("expression must be a unicode string or a node")) if isinstance(debug, list): dbg = True else: dbg = False total = 1 while total != 0: total = 0 if specific: for i in optimizations.specific_optimizations: res = i(n, rels) # Performs the optimization if res != 0 and dbg: debug.append(n.__str__()) total += res if general: for i in optimizations.general_optimizations: res = i(n) # Performs the optimization if res != 0 and dbg: debug.append(n.__str__()) total += res return n.__str__() def specific_optimize(expression, rels): '''This function performs specific optimizations. Means that it will need to know the fields used by the relations. expression : see documentation of this module rels: dic with relation name as key, and relation istance as value Return value: this will return an optimized version of the expression''' return optimize_all(expression, rels, specific=True, general=False) def general_optimize(expression): '''This function performs general optimizations. Means that it will not need to know the fields used by the relations expression : see documentation of this module Return value: this will return an optimized version of the expression''' return optimize_all(expression, None, specific=False, general=True) if __name__ == "__main__": # n=node(u"((a ᑌ b) - c ᑌ d) - b") # n=node(u"π a,b (d-a*b)") # print n.__str__() # a= tokenize("(a - (a ᑌ b) * π a,b (a-b)) - ρ 123 (a)") # a= tokenize(u"π a,b (a*b)") # a=tokenize("(a-b*c)*(b-c)") import relation import optimizations '''rels={} rels["P1"]= relation.relation("/home/salvo/dev/relational/trunk/samples/people.csv") rels["P2"]= relation.relation("/home/salvo/dev/relational/trunk/samples/people.csv") rels["R1"]= relation.relation("/home/salvo/dev/relational/trunk/samples/person_room.csv") rels["R2"]= relation.relation("/home/salvo/dev/relational/trunk/samples/person_room.csv") rels["D1"]= relation.relation("/home/salvo/dev/relational/trunk/samples/dates.csv") rels["S1"]= relation.relation("/home/salvo/dev/relational/trunk/samples/skillo.csv") print rels''' n = tree(u"π indice,qq,name (ρ age➡qq,id➡indice (P1-P2))") # n=tree("σ id==3 and indice==2 and name==5 or name<2(P1 * S1)") print n print n.toPython() # print optimizations.selection_and_product(n,rels) ''' σ skill=='C' (π id,name,chief,age (σ chief==i and age>a (ρ id➡i,age➡a(π id,age(people))*people)) ᐅᐊ skills) (π id,name,chief,age (σ chief == i and age > a ((ρ age➡a,id➡i (π id,age (people)))*people)))ᐅᐊ(σ skill == 'C' (skills)) ''' # print specific_optimize("σ name==skill and age>21 and id==indice and # skill=='C'(P1ᐅᐊS1)",rels) # print n # print n.result_format(rels) '''σ k (r) ᑌ r with r σ k (r) ᑎ r with σ k (r)''' # a=general_optimize('π indice,qq,name (ρ age➡qq,id➡indice (P1-P2))') # a=general_optimize("σ i==2 (σ b>5 (d))") # print a # print node(a) # print tokenize("(a)") relational/relational/query.py0000644000175100017510000000234212257142102016112 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # This module provides a classes to represent queries import parser class TypeException(Exception): pass class Query(object): def __init__(self, query): if not isinstance(query, unicode): raise TypeException('Expected unicode') self.query = query self.tree = parser.tree(query) # TODO self.query_code = parser self.optimized = None self.optimized_query = None self.optimized_code = None relational/relational/rtypes.py0000644000175100017510000001041512257142102016273 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relation is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # Custom types for relational algebra. # Purpose of this module is having the isFloat function and # implementing dates to use in selection. import datetime import re class rstring (str): '''String subclass with some custom methods''' def isInt(self): '''Returns true if the string represents an int number it only considers as int numbers the strings matching the following regexp: r'^[\+\-]{0,1}[0-9]+$' ''' if re.match(r'^[\+\-]{0,1}[0-9]+$', self) == None: return False else: return True def isFloat(self): '''Returns true if the string represents a float number it only considers as float numbers, the strings matching the following regexp: r'^[\+\-]{0,1}[0-9]+(\.([0-9])+)?$' ''' if re.match(r'^[\+\-]{0,1}[0-9]+(\.([0-9])+)?$', self) == None: return False else: return True def isDate(self): '''Returns true if the string represents a date, in the format YYYY-MM-DD. as separators '-' , '\', '/' are allowed. As side-effect, the date object will be stored for future usage, so no more parsings are needed ''' try: return self._isdate except: pass r = re.match( r'^([0-9]{1,4})(\\|-|/)([0-9]{1,2})(\\|-|/)([0-9]{1,2})$', self) if r == None: self._isdate = False self._date = None return False try: # Any of the following operations can generate an exception, if it happens, we aren't dealing with a date year = int(r.group(1)) month = int(r.group(3)) day = int(r.group(5)) d = datetime.date(year, month, day) self._isdate = True self._date = d return True except: self._isdate = False self._date = None return False def getDate(self): '''Returns the datetime.date object or None''' try: return self._date except: self.isDate() return self._date class rdate (object): '''Represents a date''' def __init__(self, date): '''date: A string representing a date''' if not isinstance(date, rstring): date = rstring(date) self.intdate = date.getDate() self.day = self.intdate.day self.month = self.intdate.month self.weekday = self.intdate.weekday() self.year = self.intdate.year def __hash__(self): return self.intdate.__hash__() def __str__(self): return self.intdate.__str__() def __add__(self, days): res = self.intdate + datetime.timedelta(days) return rdate(res.__str__()) def __eq__(self, other): return self.intdate == other.intdate def __ge__(self, other): return self.intdate >= other.intdate def __gt__(self, other): return self.intdate > other.intdate def __le__(self, other): return self.intdate <= other.intdate def __lt__(self, other): return self.intdate < other.intdate def __ne__(self, other): return self.intdate != other.intdate def __sub__(self, other): return (self.intdate - other.intdate).days def is_valid_relation_name(name): '''Checks if a name is valid for a relation. Returns boolean''' if re.match(r'^[_a-zA-Z]+[_a-zA-Z0-9]*$', name) == None: return False else: return True relational/relational/parallel.py0000644000175100017510000000720712257142102016546 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2009 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # This module offers capability of executing relational queries in parallel. import optimizer import multiprocessing import parser def execute(tree, rels): '''This funcion executes a query in parallel. Tree is the tree describing the query (usually obtained with parser.tree(querystring) rels is a dictionary containing the relations associated with the names''' q = multiprocessing.Queue() p = multiprocessing.Process(target=__p_exec__, args=(tree, rels, q,)) p.start() result = q.get() p.join() return result def __p_exec__(tree, rels, q): '''q is the queue used for communication''' if tree.kind == parser.RELATION: q.put(rels[tree.name]) elif tree.kind == parser.UNARY: # Obtain the relation temp_q = multiprocessing.Queue() __p_exec__(tree.child, rels, temp_q) rel = temp_q.get() # Execute the query result = __p_exec_unary__(tree, rel) q.put(result) elif tree.kind == parser.BINARY: left_q = multiprocessing.Queue() left_p = multiprocessing.Process( target=__p_exec__, args=(tree.left, rels, left_q,)) right_q = multiprocessing.Queue() right_p = multiprocessing.Process( target=__p_exec__, args=(tree.right, rels, right_q,)) # Spawn the children left_p.start() right_p.start() # Get the left and right relations left = left_q.get() right = right_q.get() # Wait for the children to terminate left_p.join() right_p.join() result = __p_exec_binary__(tree, left, right) q.put(result) return def __p_exec_binary__(tree, left, right): if tree.name == '*': return left.product(right) elif tree.name == '-': return left.difference(right) elif tree.name == 'ᑌ': return left.union(right) elif tree.name == 'ᑎ': return left.intersection(right) elif tree.name == '÷': return left.division(right) elif tree.name == 'ᐅᐊ': return left.join(right) elif tree.name == 'ᐅLEFTᐊ': return left.outer_left(right) elif tree.name == 'ᐅRIGHTᐊ': return left.outer_right(right) else: # tree.name=='ᐅFULLᐊ': return left.outer(right) def __p_exec_unary__(tree, rel): if tree.name == 'π': # Projection tree.prop = tree.prop.replace(' ', '').split(',') result = rel.projection(tree.prop) elif tree.name == "ρ": # Rename # tree.prop='{\"%s\"}' % # tree.prop.replace(',','\",\"').replace('➡','\":\"').replace(' ','') d = {} tree.prop = tree.prop.replace(' ', '') for i in tree.prop.split(','): rename_ = i.split('➡') d[rename_[0]] = rename_[1] result = rel.rename(d) else: # Selection result = rel.selection(tree.prop) return result relational/relational/parser.py0000644000175100017510000004033112257142102016241 0ustar salvosalvo# -*- coding: utf-8 -*- # coding=UTF-8 # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # # # This module implements a parser for relational algebra, and can be used # to convert expressions into python expressions and to get the parse-tree # of the expression. # # The input must be provided in UTF-8 # # # Language definition: # Query := Ident # Query := Query BinaryOp Query # Query := (Query) # Query := σ PYExprWithoutParenthesis (Query) | σ (PYExpr) (Query) # Query := π FieldList (Query) # Query := ρ RenameList (Query) # FieldList := Ident | Ident , FieldList # RenameList := Ident ➡ Ident | Ident ➡ Ident , RenameList # BinaryOp := * | - | ᑌ | ᑎ | ÷ | ᐅᐊ | ᐅLEFTᐊ | ᐅRIGHTᐊ | ᐅFULLᐊ # # Language definition here: # https://github.com/ltworf/relational/wiki/Grammar-and-language import re import rtypes RELATION = 0 UNARY = 1 BINARY = 2 PRODUCT = u'*' DIFFERENCE = u'-' UNION = u'ᑌ' INTERSECTION = u'ᑎ' DIVISION = u'÷' JOIN = u'ᐅᐊ' JOIN_LEFT = u'ᐅLEFTᐊ' JOIN_RIGHT = u'ᐅRIGHTᐊ' JOIN_FULL = u'ᐅFULLᐊ' PROJECTION = u'π' SELECTION = u'σ' RENAME = u'ρ' ARROW = u'➡' b_operators = (PRODUCT, DIFFERENCE, UNION, INTERSECTION, DIVISION, JOIN, JOIN_LEFT, JOIN_RIGHT, JOIN_FULL) # List of binary operators u_operators = (PROJECTION, SELECTION, RENAME) # List of unary operators # Associates operator with python method op_functions = { PRODUCT: 'product', DIFFERENCE: 'difference', UNION: 'union', INTERSECTION: 'intersection', DIVISION: 'division', JOIN: 'join', JOIN_LEFT: 'outer_left', JOIN_RIGHT: 'outer_right', JOIN_FULL: 'outer', PROJECTION: 'projection', SELECTION: 'selection', RENAME: 'rename'} class TokenizerException (Exception): pass class ParserException (Exception): pass class node (object): '''This class is a node of a relational expression. Leaves are relations and internal nodes are operations. The kind property says if the node is a binary operator, unary operator or relation. Since relations are leaves, a relation node will have no attribute for children. If the node is a binary operator, it will have left and right properties. If the node is a unary operator, it will have a child, pointing to the child node and a prop containing the string with the props of the operation. This class is used to convert an expression into python code.''' kind = None __hash__ = None def __init__(self, expression=None): '''Generates the tree from the tokenized expression If no expression is specified then it will create an empty node''' if expression == None or len(expression) == 0: return # If the list contains only a list, it will consider the lower level list. # This will allow things like ((((((a))))) to work while len(expression) == 1 and isinstance(expression[0], list): expression = expression[0] # The list contains only 1 string. Means it is the name of a relation if len(expression) == 1 and isinstance(expression[0], unicode): self.kind = RELATION self.name = expression[0] if not rtypes.is_valid_relation_name(self.name): raise ParserException( u"'%s' is not a valid relation name" % self.name) return '''Expression from right to left, searching for binary operators this means that binary operators have lesser priority than unary operators. It finds the operator with lesser priority, uses it as root of this (sub)tree using everything on its left as left parameter (so building a left subtree with the part of the list located on left) and doing the same on right. Since it searches for strings, and expressions into parenthesis are within sub-lists, they won't be found here, ensuring that they will have highest priority.''' for i in xrange(len(expression) - 1, -1, -1): if expression[i] in b_operators: # Binary operator self.kind = BINARY self.name = expression[i] if len(expression[:i]) == 0: raise ParserException( u"Expected left operand for '%s'" % self.name) if len(expression[i + 1:]) == 0: raise ParserException( u"Expected right operand for '%s'" % self.name) self.left = node(expression[:i]) self.right = node(expression[i + 1:]) return '''Searches for unary operators, parsing from right to left''' for i in xrange(len(expression) - 1, -1, -1): if expression[i] in u_operators: # Unary operator self.kind = UNARY self.name = expression[i] if len(expression) <= i + 2: raise ParserException( u"Expected more tokens in '%s'" % self.name) self.prop = expression[1 + i].strip() self.child = node(expression[2 + i]) return raise ParserException(u"Unable to parse tokens") pass def toCode(self): '''This method converts the tree into a python code object''' code = self.toPython() return compile(code, '', 'eval') def toPython(self): '''This method converts the expression into a python code string, which will require the relation module to be executed.''' if self.name in b_operators: return '%s.%s(%s)' % (self.left.toPython(), op_functions[self.name], self.right.toPython()) elif self.name in u_operators: prop = self.prop # Converting parameters if self.name == PROJECTION: prop = '\"%s\"' % prop.replace(' ', '').replace(',', '\",\"') elif self.name == RENAME: prop = '{\"%s\"}' % prop.replace( ',', '\",\"').replace(ARROW, '\":\"').replace(' ', '') else: # Selection prop = '\"%s\"' % prop return '%s.%s(%s)' % (self.child.toPython(), op_functions[self.name], prop) else: return self.name pass def printtree(self, level=0): '''returns a representation of the tree using indentation''' r = '' for i in range(level): r += ' ' r += self.name if self.name in b_operators: r += self.left.printtree(level + 1) r += self.right.printtree(level + 1) elif self.name in u_operators: r += '\t%s\n' % self.prop r += self.child.printtree(level + 1) return '\n' + r def get_left_leaf(self): '''This function returns the leftmost leaf in the tree. It is needed by some optimizations.''' if self.kind == RELATION: return self elif self.kind == UNARY: return self.child.get_left_leaf() elif self.kind == BINARY: return self.left.get_left_leaf() def result_format(self, rels): '''This function returns a list containing the fields that the resulting relation will have. It requires a dictionary where keys are the names of the relations and the values are the relation objects.''' if rels == None: return if self.kind == RELATION: return list(rels[self.name].header.attributes) elif self.kind == BINARY and self.name in (DIFFERENCE, UNION, INTERSECTION): return self.left.result_format(rels) elif self.kind == BINARY and self.name == DIVISION: return list(set(self.left.result_format(rels)) - set(self.right.result_format(rels))) elif self.name == PROJECTION: l = [] for i in self.prop.split(','): l.append(i.strip()) return l elif self.name == PRODUCT: return self.left.result_format(rels) + self.right.result_format(rels) elif self.name == SELECTION: return self.child.result_format(rels) elif self.name == RENAME: _vars = {} for i in self.prop.split(','): q = i.split(ARROW) _vars[q[0].strip()] = q[1].strip() _fields = self.child.result_format(rels) for i in range(len(_fields)): if _fields[i] in _vars: _fields[i] = _vars[_fields[i]] return _fields elif self.name in (JOIN, JOIN_LEFT, JOIN_RIGHT, JOIN_FULL): return list(set(self.left.result_format(rels)).union(set(self.right.result_format(rels)))) def __eq__(self, other): if not (isinstance(other, node) and self.name == other.name and self.kind == other.kind): return False if self.kind == UNARY: if other.prop != self.prop: return False return self.child == other.child if self.kind == BINARY: return self.left == other.left and self.right == other.right return True def __str__(self): if (self.kind == RELATION): return self.name elif (self.kind == UNARY): return self.name + " " + self.prop + " (" + self.child.__str__() + ")" elif (self.kind == BINARY): if self.left.kind == RELATION: le = self.left.__str__() else: le = "(" + self.left.__str__() + ")" if self.right.kind == RELATION: re = self.right.__str__() else: re = "(" + self.right.__str__() + ")" return (le + self.name + re) def _find_matching_parenthesis(expression, start=0, openpar=u'(', closepar=u')'): '''This function returns the position of the matching close parenthesis to the 1st open parenthesis found starting from start (0 by default)''' par_count = 0 # Count of parenthesis for i in range(start, len(expression)): if expression[i] == openpar: par_count += 1 elif expression[i] == closepar: par_count -= 1 if par_count == 0: return i # Closing parenthesis of the parameter def tokenize(expression): '''This function converts an expression into a list where every token of the expression is an item of a list. Expressions into parenthesis will be converted into sublists.''' if not isinstance(expression, unicode): raise TokenizerException('expected unicode') items = [] # List for the tokens '''This is a state machine. Initial status is determined by the starting of the expression. There are the following statuses: relation: this is the status if the expressions begins with something else than an operator or a parenthesis. binary operator: this is the status when parsing a binary operator, nothing much to say unary operator: this status is more complex, since it will be followed by a parameter AND a sub-expression. sub-expression: this status is entered when finding a '(' and will be exited when finding a ')'. means that the others open must be counted to determine which close is the right one.''' expression = expression.strip() # Removes initial and endind spaces state = 0 ''' 0 initial and useless 1 previous stuff was a relation 2 previous stuff was a sub-expression 3 previous stuff was a unary operator 4 previous stuff was a binary operator ''' while len(expression) > 0: if expression.startswith('('): # Parenthesis state state = 2 end = _find_matching_parenthesis(expression) if end == None: raise TokenizerException( "Missing matching ')' in '%s'" % expression) # Appends the tokenization of the content of the parenthesis items.append(tokenize(expression[1:end])) # Removes the entire parentesis and content from the expression expression = expression[end + 1:].strip() elif expression.startswith((u"σ", u"π", u"ρ")): # Unary 2 bytes items.append(expression[0:1]) #Adding operator in the top of the list expression = expression[ 1:].strip() # Removing operator from the expression if expression.startswith('('): # Expression with parenthesis, so adding what's between open and close without tokenization par = expression.find( '(', _find_matching_parenthesis(expression)) else: # Expression without parenthesis, so adding what's between start and parenthesis as whole par = expression.find('(') items.append(expression[:par].strip()) #Inserting parameter of the operator expression = expression[ par:].strip() # Removing parameter from the expression elif expression.startswith((u"÷", u"ᑎ", u"ᑌ", u"*", u"-")): items.append(expression[0]) expression = expression[1:].strip() # 1 char from the expression state = 4 elif expression.startswith(u"ᐅ"): # Binary long i = expression.find(u"ᐊ") if i == -1: raise TokenizerException(u"Expected ᐊ in %s" % (expression,)) items.append(expression[:i + 1]) expression = expression[i + 1:].strip() state = 4 elif re.match(r'[_0-9A-Za-z]', expression[0]) == None: # At this point we only have relation names, so we raise errors for anything else raise TokenizerException( "Unexpected '%c' in '%s'" % (expression[0], expression)) else: # Relation (hopefully) if state == 1: # Previous was a relation, appending to the last token i = items.pop() items.append(i + expression[0]) expression = expression[ 1:].strip() # 1 char from the expression else: state = 1 items.append(expression[0]) expression = expression[ 1:].strip() # 1 char from the expression return items def tree(expression): '''This function parses a relational algebra expression into a tree and returns the root node using the Node class defined in this module.''' return node(tokenize(expression)) def parse(expr): '''This function parses a relational algebra expression, converting it into python, executable by eval function to get the result of the expression. It has 2 class of operators: without parameters *, -, ᑌ, ᑎ, ᐅᐊ, ᐅLEFTᐊ, ᐅRIGHTᐊ, ᐅFULLᐊ with parameters: σ, π, ρ Syntax for operators without parameters is: relation operator relation Syntax for operators with parameters is: operator parameters (relation) Since a*b is a relation itself, you can parse π a,b (a*b). And since π a,b (A) is a relation, you can parse π a,b (A) ᑌ B. You can use parenthesis to change priority: a ᐅᐊ (q ᑌ d). IMPORTANT: all strings must be unicode EXAMPLES σage > 25 and rank == weight(A) Q ᐅᐊ π a,b(A) ᐅᐊ B ρid➡i,name➡n(A) - π a,b(π a,b(A)) ᑎ σage > 25 or rank = weight(A) π a,b(π a,b(A)) ρid➡i,name➡n(π a,b(A)) A ᐅᐊ B ''' return tree(expr).toPython() if __name__ == "__main__": while True: e = unicode(raw_input("Expression: "), 'utf-8') print parse(e) # b=u"σ age>1 and skill=='C' (peopleᐅᐊskills)" # print b[0] # parse(b) pass relational/relational/__init__.py0000644000175100017510000000016312257142102016503 0ustar salvosalvo__all__ = ( "relation", "parser", "optimizer", "optimizations", "rtypes", "parallel", ) relational/relational/optimizations.py0000644000175100017510000005003412257142102017657 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2009 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # This module contains functions to perform various optimizations on the expression trees. # The list general_optimizations contains pointers to general functions, so they can be called # within a cycle. # # It is possible to add new general optimizations by adding the function in the list # general_optimizations present in this module. And the optimization will be executed with the # other ones when optimizing. # # A function will have one parameter, which is the root node of the tree describing the expression. # The class used is defined in optimizer module. # A function will have to return the number of changes performed on the tree. import parser from cStringIO import StringIO from tokenize import generate_tokens sel_op = ( '//=', '**=', 'and', 'not', 'in', '//', '**', '<<', '>>', '==', '!=', '>=', '<=', '+=', '-=', '*=', '/=', '%=', 'or', '+', '-', '*', '/', '&', '|', '^', '~', '<', '>', '%', '=', '(', ')', ',', '[', ']') PRODUCT = parser.PRODUCT DIFFERENCE = parser.DIFFERENCE UNION = parser.UNION INTERSECTION = parser.INTERSECTION DIVISION = parser.DIVISION JOIN = parser.JOIN JOIN_LEFT = parser.JOIN_LEFT JOIN_RIGHT = parser.JOIN_RIGHT JOIN_FULL = parser.JOIN_FULL PROJECTION = parser.PROJECTION SELECTION = parser.SELECTION RENAME = parser.RENAME ARROW = parser.ARROW def replace_node(replace, replacement): '''This function replaces "replace" node with the node "with", the father of the node will now point to the with node''' replace.name = replacement.name replace.kind = replacement.kind if replace.kind == parser.UNARY: replace.child = replacement.child replace.prop = replacement.prop elif replace.kind == parser.BINARY: replace.right = replacement.right replace.left = replacement.left def recoursive_scan(function, node, rels=None): '''Does a recoursive optimization on the tree. This function will recoursively execute the function given as "function" parameter starting from node to all the tree. if rels is provided it will be passed as argument to the function. Otherwise the function will be called just on the node. Result value: function is supposed to return the amount of changes it has performed on the tree. The various result will be added up and this final value will be the returned value.''' changes = 0 # recoursive scan if node.kind == parser.UNARY: if rels != None: changes += function(node.child, rels) else: changes += function(node.child) elif node.kind == parser.BINARY: if rels != None: changes += function(node.right, rels) changes += function(node.left, rels) else: changes += function(node.right) changes += function(node.left) return changes def duplicated_select(n): '''This function locates and deletes things like σ a ( σ a(C)) and the ones like σ a ( σ b(C)) replacing the 1st one with a single select and the 2nd one with a single select with both conditions in and ''' changes = 0 if n.name == SELECTION and n.child.name == SELECTION: if n.prop != n.child.prop: # Nested but different, joining them n.prop = n.prop + " and " + n.child.prop # This adds parenthesis if they are needed if n.child.prop.startswith('(') or n.prop.startswith('('): n.prop = '(%s)' % n.prop n.child = n.child.child changes = 1 changes += duplicated_select(n) return changes + recoursive_scan(duplicated_select, n) def futile_union_intersection_subtraction(n): '''This function locates things like r ᑌ r, and replaces them with r. R ᑌ R --> R R ᑎ R --> R R - R --> σ False (R) σ k (R) - R --> σ False (R) R - σ k (R) --> σ not k (R) σ k (R) ᑌ R --> R σ k (R) ᑎ R --> σ k (R) ''' changes = 0 # Union and intersection of the same thing if n.name in (UNION, INTERSECTION) and n.left == n.right: changes = 1 replace_node(n, n.left) # selection and union of the same thing elif (n.name == UNION): if n.left.name == SELECTION and n.left.child == n.right: changes = 1 replace_node(n, n.right) elif n.right.name == SELECTION and n.right.child == n.left: changes = 1 replace_node(n, n.left) # selection and intersection of the same thing elif n.name == INTERSECTION: if n.left.name == SELECTION and n.left.child == n.right: changes = 1 replace_node(n, n.left) elif n.right.name == SELECTION and n.right.child == n.left: changes = 1 replace_node(n, n.right) # Subtraction and selection of the same thing elif (n.name == DIFFERENCE and (n.right.name == SELECTION and n.right.child == n.left)): # Subtraction of two equal things, but one has a selection n.name = n.right.name n.kind = n.right.kind n.child = n.right.child n.prop = '(not (%s))' % n.right.prop n.left = n.right = None # Subtraction of the same thing or with selection on the left child elif (n.name == DIFFERENCE and ((n.left == n.right) or (n.left.name == SELECTION and n.left.child == n.right))): # Empty relation changes = 1 n.kind = parser.UNARY n.name = SELECTION n.prop = 'False' n.child = n.left.get_left_leaf() # n.left=n.right=None return changes + recoursive_scan(futile_union_intersection_subtraction, n) def down_to_unions_subtractions_intersections(n): '''This funcion locates things like σ i==2 (c ᑌ d), where the union can be a subtraction and an intersection and replaces them with σ i==2 (c) ᑌ σ i==2(d). ''' changes = 0 _o = (UNION, DIFFERENCE, INTERSECTION) if n.name == SELECTION and n.child.name in _o: left = parser.node() left.prop = n.prop left.name = n.name left.child = n.child.left left.kind = parser.UNARY right = parser.node() right.prop = n.prop right.name = n.name right.child = n.child.right right.kind = parser.UNARY n.name = n.child.name n.left = left n.right = right n.child = None n.prop = None n.kind = parser.BINARY changes += 1 return changes + recoursive_scan(down_to_unions_subtractions_intersections, n) def duplicated_projection(n): '''This function locates thing like π i ( π j (R)) and replaces them with π i (R)''' changes = 0 if n.name == PROJECTION and n.child.name == PROJECTION: n.child = n.child.child changes += 1 return changes + recoursive_scan(duplicated_projection, n) def selection_inside_projection(n): '''This function locates things like σ j (π k(R)) and converts them into π k(σ j (R))''' changes = 0 if n.name == SELECTION and n.child.name == PROJECTION: changes = 1 temp = n.prop n.prop = n.child.prop n.child.prop = temp n.name = PROJECTION n.child.name = SELECTION return changes + recoursive_scan(selection_inside_projection, n) def swap_union_renames(n): '''This function locates things like ρ a➡b(R) ᑌ ρ a➡b(Q) and replaces them with ρ a➡b(R ᑌ Q). Does the same with subtraction and intersection''' changes = 0 if n.name in (DIFFERENCE, UNION, INTERSECTION) and n.left.name == n.right.name and n.left.name == RENAME: l_vars = {} for i in n.left.prop.split(','): q = i.split(ARROW) l_vars[q[0].strip()] = q[1].strip() r_vars = {} for i in n.right.prop.split(','): q = i.split(ARROW) r_vars[q[0].strip()] = q[1].strip() if r_vars == l_vars: changes = 1 # Copying self, but child will be child of renames q = parser.node() q.name = n.name q.kind = parser.BINARY q.left = n.left.child q.right = n.right.child n.name = RENAME n.kind = parser.UNARY n.child = q n.prop = n.left.prop n.left = n.right = None return changes + recoursive_scan(swap_union_renames, n) def futile_renames(n): '''This function purges renames like id->id''' changes = 0 if n.name == RENAME: # Located two nested renames. changes = 1 # Creating a dictionary with the attributes _vars = {} for i in n.prop.split(','): q = i.split(ARROW) _vars[q[0].strip()] = q[1].strip() # Scans dictionary to locate things like "a->b,b->c" and replace them # with "a->c" for key in list(_vars.keys()): try: value = _vars[key] except: value = None if key == value: _vars.pop(value) # Removes the unused one # Reset prop var n.prop = "" # Generates new prop var for i in _vars.items(): n.prop += u"%s%s%s," % (i[0], ARROW, i[1]) n.prop = n.prop[:-1] # Removing ending comma if len(n.prop) == 0: # Nothing to rename, removing the rename op replace_node(n, n.child) return changes + recoursive_scan(futile_renames, n) def subsequent_renames(n): '''This function removes redoundant subsequent renames joining them into one''' '''Purges renames like id->id Since it's needed to be performed BEFORE this one so it is not in the list with the other optimizations''' futile_renames(n) changes = 0 if n.name == RENAME and n.child.name == n.name: # Located two nested renames. changes = 1 # Joining the attribute into one n.prop += ',' + n.child.prop n.child = n.child.child # Creating a dictionary with the attributes _vars = {} for i in n.prop.split(','): q = i.split(ARROW) _vars[q[0].strip()] = q[1].strip() # Scans dictionary to locate things like "a->b,b->c" and replace them # with "a->c" for key in list(_vars.keys()): try: value = _vars[key] except: value = None if value in _vars.keys(): if _vars[value] != key: # Double rename on attribute _vars[key] = _vars[_vars[key]] # Sets value _vars.pop(value) # Removes the unused one else: # Cycle rename a->b,b->a _vars.pop(value) # Removes the unused one _vars.pop(key) # Removes the unused one # Reset prop var n.prop = "" # Generates new prop var for i in _vars.items(): n.prop += u"%s%s%s," % (i[0], ARROW, i[1]) n.prop = n.prop[:-1] # Removing ending comma if len(n.prop) == 0: # Nothing to rename, removing the rename op replace_node(n, n.child) return changes + recoursive_scan(subsequent_renames, n) class level_string(str): level = 0 def tokenize_select(expression): '''This function returns the list of tokens present in a selection. The expression can contain parenthesis. It will use a subclass of str with the attribute level, which will specify the nesting level of the token into parenthesis.''' g = generate_tokens(StringIO(str(expression)).readline) l = list(token[1] for token in g) l.remove('') # Changes the 'a','.','method' token group into a single 'a.method' token try: while True: dot = l.index('.') l[dot] = '%s.%s' % (l[dot - 1], l[dot + 1]) l.pop(dot + 1) l.pop(dot - 1) except: pass level = 0 for i in range(len(l)): l[i] = level_string(l[i]) l[i].level = level if l[i] == '(': level += 1 elif l[i] == ')': level -= 1 return l def swap_rename_projection(n): '''This function locates things like π k(ρ j(R)) and replaces them with ρ j(π k(R)). This will let rename work on a hopefully smaller set and more important, will hopefully allow further optimizations. Will also eliminate fields in the rename that are cutted in the projection. ''' changes = 0 if n.name == PROJECTION and n.child.name == RENAME: changes = 1 # π index,name(ρ id➡index(R)) _vars = {} for i in n.child.prop.split(','): q = i.split(ARROW) _vars[q[1].strip()] = q[0].strip() _pr = n.prop.split(',') for i in range(len(_pr)): try: _pr[i] = _vars[_pr[i].strip()] except: pass _pr_reborn = n.prop.split(',') for i in list(_vars.keys()): if i not in _pr_reborn: _vars.pop(i) n.name = n.child.name n.prop = '' for i in _vars.keys(): n.prop += u'%s%s%s,' % (_vars[i], ARROW, i) n.prop = n.prop[:-1] n.child.name = PROJECTION n.child.prop = '' for i in _pr: n.child.prop += i + ',' n.child.prop = n.child.prop[:-1] return changes + recoursive_scan(swap_rename_projection, n) def swap_rename_select(n): '''This function locates things like σ k(ρ j(R)) and replaces them with ρ j(σ k(R)). Renaming the attributes used in the selection, so the operation is still valid.''' changes = 0 if n.name == SELECTION and n.child.name == RENAME: changes = 1 # Dictionary containing attributes of rename _vars = {} for i in n.child.prop.split(','): q = i.split(ARROW) _vars[q[1].strip()] = q[0].strip() # tokenizes expression in select _tokens = tokenize_select(n.prop) # Renaming stuff for i in range(len(_tokens)): splitted = _tokens[i].split('.', 1) if splitted[0] in _vars: if len(splitted) == 1: _tokens[i] = _vars[_tokens[i].split('.')[0]] else: _tokens[i] = _vars[ _tokens[i].split('.')[0]] + '.' + splitted[1] # Swapping operators n.name = RENAME n.child.name = SELECTION n.prop = n.child.prop n.child.prop = '' for i in _tokens: n.child.prop += i + ' ' return changes + recoursive_scan(swap_rename_select, n) def select_union_intersect_subtract(n): '''This function locates things like σ i(a) ᑌ σ q(a) and replaces them with σ (i OR q) (a) Removing a O(n²) operation like the union''' changes = 0 if n.name in (UNION, INTERSECTION, DIFFERENCE) and n.left.name == SELECTION and n.right.name == SELECTION and n.left.child == n.right.child: cahnges = 1 d = {UNION: 'or', INTERSECTION: 'and', DIFFERENCE: 'and not'} op = d[n.name] newnode = parser.node() if n.left.prop.startswith('(') or n.right.prop.startswith('('): t_str = '(' if n.left.prop.startswith('('): t_str += '(%s)' else: t_str += '%s' t_str += ' %s ' if n.right.prop.startswith('('): t_str += '(%s)' else: t_str += '%s' t_str += ')' newnode.prop = t_str % (n.left.prop, op, n.right.prop) else: newnode.prop = '%s %s %s' % (n.left.prop, op, n.right.prop) newnode.name = SELECTION newnode.child = n.left.child newnode.kind = parser.UNARY replace_node(n, newnode) return changes + recoursive_scan(select_union_intersect_subtract, n) def selection_and_product(n, rels): '''This function locates things like σ k (R*Q) and converts them into σ l (σ j (R) * σ i (Q)). Where j contains only attributes belonging to R, i contains attributes belonging to Q and l contains attributes belonging to both''' changes = 0 if n.name == SELECTION and n.child.name in (PRODUCT, JOIN, JOIN_LEFT, JOIN_RIGHT, JOIN_FULL): l_attr = n.child.left.result_format(rels) r_attr = n.child.right.result_format(rels) tokens = tokenize_select(n.prop) groups = [] temp = [] for i in tokens: if i == 'and' and i.level == 0: groups.append(temp) temp = [] else: temp.append(i) if len(temp) != 0: groups.append(temp) temp = [] left = [] right = [] both = [] for i in groups: l_fields = False # has fields in left? r_fields = False # has fields in left? for j in set(i).difference(sel_op): j = j.split('.')[0] if j in l_attr: # Field in left l_fields = True if j in r_attr: # Field in right r_fields = True if l_fields and r_fields: # Fields in both both.append(i) elif l_fields: left.append(i) elif r_fields: right.append(i) else: # Unknown.. adding in both both.append(i) # Preparing left selection if len(left) > 0: changes = 1 l_node = parser.node() l_node.name = SELECTION l_node.kind = parser.UNARY l_node.child = n.child.left l_node.prop = '' n.child.left = l_node while len(left) > 0: c = left.pop(0) for i in c: l_node.prop += i + ' ' if len(left) > 0: l_node.prop += ' and ' if '(' in l_node.prop: l_node.prop = '(%s)' % l_node.prop # Preparing right selection if len(right) > 0: changes = 1 r_node = parser.node() r_node.name = SELECTION r_node.prop = '' r_node.kind = parser.UNARY r_node.child = n.child.right n.child.right = r_node while len(right) > 0: c = right.pop(0) for i in c: r_node.prop += i + ' ' if len(right) > 0: r_node.prop += ' and ' if '(' in r_node.prop: r_node.prop = '(%s)' % r_node.prop # Changing main selection n.prop = '' if len(both) != 0: while len(both) > 0: c = both.pop(0) for i in c: n.prop += i + ' ' if len(both) > 0: n.prop += ' and ' if '(' in n.prop: n.prop = '(%s)' % n.prop else: # No need for general select replace_node(n, n.child) return changes + recoursive_scan(selection_and_product, n, rels) general_optimizations = [ duplicated_select, down_to_unions_subtractions_intersections, duplicated_projection, selection_inside_projection, subsequent_renames, swap_rename_select, futile_union_intersection_subtraction, swap_union_renames, swap_rename_projection, select_union_intersect_subtract] specific_optimizations = [selection_and_product] if __name__ == "__main__": print tokenize_select("skill == 'C' and id % 2 == 0") relational/COPYING0000644000175100017510000010451312257142102013277 0ustar salvosalvo GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . relational/CHANGELOG0000644000175100017510000001501712257142102013456 0ustar salvosalvo1.2 - Better tokenizer, gives more indicative errors - Parser gives more indicative errors - Improved select_union_intersect_subtract optimization to avoid parenthesis whenever possible - Moved feedback service, and added the code for it - Different way of checking the latest version - Removed support for pyside 1.1 - Incorrect relational operations now raise an exception instead of returning None - Forces relations to have correct names for attributes - Colored output in readline mode - Can send email in survey - Can check for new version online - Can use both PySide and PyQt - Removed buttons for adding and deleting tuples - Can edit relations within the GUI - API migrated to unicode (instead of utf-8 encoded strings) 1.0 - Adds history in the GUI - Adds menus to the GUI - Checks if given name to relations are valid - Discards the old and not so functional tlb format - Float type recognition is more robust, now handled using a regexp - Date type recognition is more robust, now using a combination of regexp plus date object - Integer type recognition now allows negative numbers in relations - Rename operations are now much faster, content won't be copied unless subsequent updates, insert, updates or deletes will occur - Added testsuite - Module parallel does something, can execute queries in parallel - Implemented select_union_intersect_subtract general optimization - Removed encoding from .desktop file (was deprecated) - Added manpage for relational-cli - Internally uses set instead of lists to describe relation's content - Tuples are internally mapped on tuples and no longer on lists - Set hash method for the classes - Parsing of strings representing dates is now cached, eliminating the need for double parse - Fixed python expression tokenization, now uses native tokenizer - Fixed optimization involving selection and parenthesis in the expression (Rev 260) - Fixed futile_union_intersection_subtraction optimization that didn't work when selection operator was in the left subtree (Rev 261) - Restyle of the GUI, splitters added 0.11 - Font is set only on windows (Rev 206) - Improved futile_union_intersection_subtraction in case of A-A, when A is a sub-query (Rev 208) - Improved futile_union_intersection_subtraction, handles when a branch of subtracion has a selection (Rev 209) - Can load relations specified in command line (Rev 210) - Using fakeroot instead of su in make debian (Rev 214) - Fixed problem with float numbers with selection of certain relations (Rev 215) - Added .desktop file on svn (Rev 216) - Automatically fills some fields in the survey (Rev 217) - When a query fails, shows the message of the exception (Rev220) - Improved tokenizer for select in optimizations, now can accept operators in identifiers (Rev 220) - Uses getopt to handle the command line in a more standard way - Organized code so the ui can be either qt or command line - Does not depend on QT anymore - Added readline user interface - Added division operator 0.10 - In optimizer, added a function that tokenizes an expression - Document about complexity of operations - Bug: error in update operation, it changed the original tuple, so also other relations using the same tuple would change. Now it copies it. - Added make install and uninstall - Optimizer generate a tree from the expression - Uses python-psyco when it is available - Ability to perform optimizations from GUI - Able to (temporarily) store queries with a name - Mechanism to add new kind of optimizations, without having to edit all the code - Implemented duplicated_select general optimization - Implemented down_to_unions_subtractions_intersections general optimization - Implemented duplicated_projection general optimization - Implemented selection_inside_projection general optimization - Implemented subsequent_renames general optimization - Implemented swap_rename_select general optimization - Implemented selection_and_product specific optimization - Added stub for converting SQL to relational algebra - Implemented futile_union_intersection_subtraction general optimization - Implemented swap_rename_projection general optimization - Replaced old relational algebra to python compiler with new one based on the new tokenizer/parser (Rev 188) - Code refactory to move the new parser into parser.py out of optimizer.py, that will still be compatible (Rev 190) - Selection can now accept expressions with parenthesis 0.9 - Splitted into independent packages (gui and library) - Simplified makefile, bringing outside files for debian package - Default source package now doesn't contain informations to generate debian/mac packages - "make source_all" generates the old style tarball containing all the files - Bug: relational script installed with debian package now passes arguments to the python executable - Insert and delete from GUI are now done on the displayed relation, not on the selected one 0.8 - Added __eq__ to relation object, will compare ignoring order. - New default relation's format is csv, as defined in RFC4180 - Converted sample's relations to csv - Deb postinstall generates optimized files, this will increase loading speed - Relation module has SQL-like delete - Relation module has SQL-like update - Relation module has SQL-like insert - GUI can be used to insert and delete tuples - Showing fields of selected relation will work with themes different than oxygen 0.7 - Added README - Expressions between quotes aren't parsed anymore - When adding a relation, the file must be chosen 1st, and then the default relation's name is the same as the filename - Changed internal rename method. Now uses a dictionary - Optimized saving of relations - Can save relations from gui - Outer join methods simplified - Form to send a survey - Makefile to create .deb package 0.6 - Fixes to run on Mac OsX - Added Makefile - Able to create .app MacOsX files using "make app" - Able to create tar.gz file containing Mac OsX application and samples using "make mac" 0.5 - Added support for float numbers - Added support for dates 0.4 - Created GUI 0.3 - Added support for parenthesis in relational queries 0.2 - Created parser module - Created function to parse expression with operators without parameters - Created recoursive function to parse expressions 0.1 - Created header class to handle attributes - Created relation class - Added union - Added intersection - Added difference - Added product - Added projection - Added rename - Projection can use a list or several parameters - Added selection - Added left join - Added right join - Added capability of operation even if attributes aren't in the same order - Added full outher join relational/driver.py0000755000175100017510000001675612257142102014127 0ustar salvosalvo#!/usr/bin/env python # -*- coding: utf-8 -*- # coding=UTF-8 # Relational # Copyright (C) 2010 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli import os from sys import exit from relational import relation, parser, optimizer from xtermcolor import colorize COLOR_RED = 0xff0000 COLOR_GREEN = 0x00ff00 COLOR_MAGENTA = 0xff00ff COLOR_CYAN = 0x00ffff print relation rels = {} examples_path = 'samples/' tests_path = 'test/' def readfile(fname): '''Reads a file as string and returns its content''' fd = open(fname) expr = fd.read() fd.close() return expr def load_relations(): '''Loads all the relations present in the directory indicated in the examples_path variable and stores them in the rels dictionary''' print "Loading relations" for i in os.listdir(examples_path): if i.endswith('.csv'): # It's a relation, loading it # Naming the relation relname = i[:-4] print ("Loading relation %s with name %s..." % (i, relname)), rels[relname] = relation.relation('%s%s' % (examples_path, i)) print 'done' def execute_tests(): py_bad = 0 py_good = 0 py_tot = 0 q_bad = 0 q_good = 0 q_tot = 0 ex_bad = 0 ex_good = 0 ex_tot = 0 for i in os.listdir(tests_path): if i.endswith('.query'): q_tot += 1 if run_test(i[:-6]): q_good += 1 else: q_bad += 1 elif i.endswith('.python'): py_tot += 1 if run_py_test(i[:-7]): py_good += 1 else: py_bad += 1 elif i.endswith('.exec'): ex_tot += 1 if run_exec_test(i[:-5]): ex_good += 1 else: ex_bad += 1 print colorize("Resume of the results", COLOR_CYAN) print colorize("Query tests", COLOR_MAGENTA) print "Total test count: %d" % q_tot print "Passed tests: %d" % q_good if q_bad > 0: print colorize("Failed tests count: %d" % q_bad, COLOR_RED) print colorize("Python tests", COLOR_MAGENTA) print "Total test count: %d" % py_tot print "Passed tests: %d" % py_good if py_bad > 0: print colorize("Failed tests count: %d" % py_bad, COLOR_RED) print colorize("Execute Python tests", COLOR_MAGENTA) print "Total test count: %d" % ex_tot print "Passed tests: %d" % ex_good if ex_bad > 0: print colorize("Failed tests count: %d" % ex_bad, COLOR_RED) print colorize("Total results", COLOR_CYAN) if q_bad + py_bad + ex_bad == 0: print colorize("No failed tests", COLOR_GREEN) return 0 else: print colorize("There are %d failed tests" % (py_bad + q_bad + ex_bad), COLOR_RED) return 1 def run_exec_test(testname): '''Runs a python test, which executes code directly rather than queries''' print "Running python test: " + colorize(testname, COLOR_MAGENTA) glob = rels.copy() exp_result = {} try: expr = readfile('%s%s.exec' % (tests_path, testname)) exec(expr, glob) # Evaluating the expression expr = readfile('%s%s.exec' % (tests_path, testname)) exec(expr, glob) # Evaluating the expression expr = readfile('%s%s.result' % (tests_path, testname)) exp_result = eval(expr, rels) # Evaluating the expression if isinstance(exp_result, dict): fields_ok = True for i in exp_result: fields_ok = fields_ok and glob[i] == exp_result[i] if fields_ok: print colorize('Test passed', COLOR_GREEN) return True except: pass print colorize('ERROR', COLOR_RED) print colorize('=====================================', COLOR_RED) print "Expected %s" % exp_result # print "Got %s" % result print colorize('=====================================', COLOR_RED) return False def run_py_test(testname): '''Runs a python test, which evaluates expressions directly rather than queries''' print "Running expression python test: " + colorize(testname, COLOR_MAGENTA) try: expr = readfile('%s%s.python' % (tests_path, testname)) result = eval(expr, rels) # Evaluating the expression expr = readfile('%s%s.result' % (tests_path, testname)) exp_result = eval(expr, rels) # Evaluating the expression if result == exp_result: print colorize('Test passed', COLOR_GREEN) return True except: pass print colorize('ERROR', COLOR_RED) print colorize('=====================================', COLOR_RED) print "Expected %s" % exp_result print "Got %s" % result print colorize('=====================================', COLOR_RED) return False def run_test(testname): '''Runs a specific test executing the file testname.query and comparing the result with testname.result The query will be executed both unoptimized and optimized''' print "Running test: " + colorize(testname, COLOR_MAGENTA) query = None expr = None o_query = None o_expr = None result_rel = None result = None o_result = None try: result_rel = relation.relation('%s%s.result' % (tests_path, testname)) query = unicode( readfile('%s%s.query' % (tests_path, testname)).strip(), 'utf8') o_query = optimizer.optimize_all(query, rels) expr = parser.parse(query) # Converting expression to python string result = eval(expr, rels) # Evaluating the expression o_expr = parser.parse( o_query) # Converting expression to python string o_result = eval(o_expr, rels) # Evaluating the expression c_expr = parser.tree(query).toCode() # Converting to python code c_result = eval(c_expr, rels) if (o_result == result_rel) and (result == result_rel) and (c_result == result_rel): print colorize('Test passed', COLOR_GREEN) return True except Exception as inst: print inst pass print colorize('ERROR', COLOR_RED) print "Query: %s -> %s" % (query, expr) print "Optimized query: %s -> %s" % (o_query, o_expr) print colorize('=====================================', COLOR_RED) print colorize("Expected result", COLOR_GREEN) print result_rel print colorize("Result", COLOR_RED) print result print colorize("Optimized result", COLOR_RED) print o_result print colorize("optimized result match %s" % str(result_rel == o_result), COLOR_MAGENTA) print colorize("result match %s" % str(result == result_rel), COLOR_MAGENTA) print colorize('=====================================', COLOR_RED) return False if __name__ == '__main__': print "-> Starting testsuite for relational" load_relations() print "-> Starting tests" exit(execute_tests()) relational/relational_gui/0000755000175100017510000000000012257142102015236 5ustar salvosalvorelational/relational_gui/survey.ui0000644000175100017510000002370112257142102017135 0ustar salvosalvo Form 0 0 422 313 Survey Country txtCountry School txtSchool Age txtAge How did you find relational txtFind System txtSystem Comments txtComments true Email (only if you want a reply) txtEmail Qt::Horizontal 40 20 Cancel Clear Send true txtSystem txtCountry txtSchool txtAge txtFind txtEmail txtComments cmdSend cmdClear cmdCancel cmdCancel clicked() Form close() 202 384 180 319 cmdClear clicked() txtComments clear() 265 384 291 248 cmdClear clicked() txtFind clear() 265 384 400 151 cmdClear clicked() txtAge clear() 265 384 257 123 cmdClear clicked() txtSchool clear() 265 384 317 87 cmdClear clicked() txtCountry clear() 265 384 400 70 cmdClear clicked() txtSystem clear() 265 384 400 39 txtSystem returnPressed() txtCountry setFocus() 213 22 224 52 txtCountry returnPressed() txtSchool setFocus() 268 54 276 89 txtSchool returnPressed() txtAge setFocus() 355 85 358 118 txtAge returnPressed() txtFind setFocus() 375 123 400 151 cmdSend clicked() Form send() 327 384 396 320 cmdClear clicked() txtEmail clear() 233 367 242 168 txtFind returnPressed() txtEmail setFocus() 302 140 302 167 txtEmail returnPressed() txtComments setFocus() 302 167 302 255 send() relational/relational_gui/survey.py0000644000175100017510000002005512257142102017147 0ustar salvosalvo# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'relational_gui/survey.ui' # # Created: Fri Dec 27 00:23:51 2013 # by: PyQt4 UI code generator 4.10.3 # # WARNING! All changes made in this file will be lost! from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s try: _encoding = QtGui.QApplication.UnicodeUTF8 def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) class Ui_Form(object): def setupUi(self, Form): Form.setObjectName(_fromUtf8("Form")) Form.resize(422, 313) Form.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.verticalLayout = QtGui.QVBoxLayout(Form) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.formLayout = QtGui.QGridLayout() self.formLayout.setObjectName(_fromUtf8("formLayout")) self.txtSystem = QtGui.QLineEdit(Form) self.txtSystem.setObjectName(_fromUtf8("txtSystem")) self.formLayout.addWidget(self.txtSystem, 0, 1, 1, 1) self.label = QtGui.QLabel(Form) self.label.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label.setObjectName(_fromUtf8("label")) self.formLayout.addWidget(self.label, 1, 0, 1, 1) self.txtCountry = QtGui.QLineEdit(Form) self.txtCountry.setObjectName(_fromUtf8("txtCountry")) self.formLayout.addWidget(self.txtCountry, 1, 1, 1, 1) self.label_2 = QtGui.QLabel(Form) self.label_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_2.setObjectName(_fromUtf8("label_2")) self.formLayout.addWidget(self.label_2, 2, 0, 1, 1) self.txtSchool = QtGui.QLineEdit(Form) self.txtSchool.setObjectName(_fromUtf8("txtSchool")) self.formLayout.addWidget(self.txtSchool, 2, 1, 1, 1) self.label_3 = QtGui.QLabel(Form) self.label_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_3.setObjectName(_fromUtf8("label_3")) self.formLayout.addWidget(self.label_3, 3, 0, 1, 1) self.txtAge = QtGui.QLineEdit(Form) self.txtAge.setObjectName(_fromUtf8("txtAge")) self.formLayout.addWidget(self.txtAge, 3, 1, 1, 1) self.label_4 = QtGui.QLabel(Form) self.label_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_4.setObjectName(_fromUtf8("label_4")) self.formLayout.addWidget(self.label_4, 4, 0, 1, 1) self.txtFind = QtGui.QLineEdit(Form) self.txtFind.setObjectName(_fromUtf8("txtFind")) self.formLayout.addWidget(self.txtFind, 4, 1, 1, 1) self.label_5 = QtGui.QLabel(Form) self.label_5.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.label_5.setObjectName(_fromUtf8("label_5")) self.formLayout.addWidget(self.label_5, 0, 0, 1, 1) self.label_6 = QtGui.QLabel(Form) self.label_6.setObjectName(_fromUtf8("label_6")) self.formLayout.addWidget(self.label_6, 6, 0, 1, 1) self.txtComments = QtGui.QTextEdit(Form) self.txtComments.setTabChangesFocus(True) self.txtComments.setObjectName(_fromUtf8("txtComments")) self.formLayout.addWidget(self.txtComments, 6, 1, 1, 1) self.label_7 = QtGui.QLabel(Form) self.label_7.setObjectName(_fromUtf8("label_7")) self.formLayout.addWidget(self.label_7, 5, 0, 1, 1) self.txtEmail = QtGui.QLineEdit(Form) self.txtEmail.setObjectName(_fromUtf8("txtEmail")) self.formLayout.addWidget(self.txtEmail, 5, 1, 1, 1) self.verticalLayout.addLayout(self.formLayout) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.cmdCancel = QtGui.QPushButton(Form) self.cmdCancel.setObjectName(_fromUtf8("cmdCancel")) self.horizontalLayout.addWidget(self.cmdCancel) self.cmdClear = QtGui.QPushButton(Form) self.cmdClear.setObjectName(_fromUtf8("cmdClear")) self.horizontalLayout.addWidget(self.cmdClear) self.cmdSend = QtGui.QPushButton(Form) self.cmdSend.setDefault(True) self.cmdSend.setObjectName(_fromUtf8("cmdSend")) self.horizontalLayout.addWidget(self.cmdSend) self.verticalLayout.addLayout(self.horizontalLayout) self.label.setBuddy(self.txtCountry) self.label_2.setBuddy(self.txtSchool) self.label_3.setBuddy(self.txtAge) self.label_4.setBuddy(self.txtFind) self.label_5.setBuddy(self.txtSystem) self.label_6.setBuddy(self.txtComments) self.label_7.setBuddy(self.txtEmail) self.retranslateUi(Form) QtCore.QObject.connect(self.cmdCancel, QtCore.SIGNAL(_fromUtf8("clicked()")), Form.close) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtComments.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtFind.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtAge.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtSchool.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtCountry.clear) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtSystem.clear) QtCore.QObject.connect(self.txtSystem, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.txtCountry.setFocus) QtCore.QObject.connect(self.txtCountry, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.txtSchool.setFocus) QtCore.QObject.connect(self.txtSchool, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.txtAge.setFocus) QtCore.QObject.connect(self.txtAge, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.txtFind.setFocus) QtCore.QObject.connect(self.cmdSend, QtCore.SIGNAL(_fromUtf8("clicked()")), Form.send) QtCore.QObject.connect(self.cmdClear, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtEmail.clear) QtCore.QObject.connect(self.txtFind, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.txtEmail.setFocus) QtCore.QObject.connect(self.txtEmail, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.txtComments.setFocus) QtCore.QMetaObject.connectSlotsByName(Form) Form.setTabOrder(self.txtSystem, self.txtCountry) Form.setTabOrder(self.txtCountry, self.txtSchool) Form.setTabOrder(self.txtSchool, self.txtAge) Form.setTabOrder(self.txtAge, self.txtFind) Form.setTabOrder(self.txtFind, self.txtEmail) Form.setTabOrder(self.txtEmail, self.txtComments) Form.setTabOrder(self.txtComments, self.cmdSend) Form.setTabOrder(self.cmdSend, self.cmdClear) Form.setTabOrder(self.cmdClear, self.cmdCancel) def retranslateUi(self, Form): Form.setWindowTitle(_translate("Form", "Survey", None)) self.label.setText(_translate("Form", "Country", None)) self.label_2.setText(_translate("Form", "School", None)) self.label_3.setText(_translate("Form", "Age", None)) self.label_4.setText(_translate("Form", "How did you find relational", None)) self.label_5.setText(_translate("Form", "System", None)) self.label_6.setText(_translate("Form", "Comments", None)) self.label_7.setText(_translate("Form", "Email (only if you want a reply)", None)) self.cmdCancel.setText(_translate("Form", "Cancel", None)) self.cmdClear.setText(_translate("Form", "Clear", None)) self.cmdSend.setText(_translate("Form", "Send", None)) relational/relational_gui/rel_edit.ui0000644000175100017510000001032512257142102017365 0ustar salvosalvo Dialog 0 0 594 444 Relation editor Edit Add tuple Remove tuple Add column Remove column Remember that new relations and modified relations are not automatically saved Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 328 354 157 274 buttonBox rejected() Dialog reject() 396 360 286 274 cmdAddColumn clicked() Dialog addColumn() 71 95 188 100 cmdRemoveColumn clicked() Dialog deleteColumn() 126 121 202 129 cmdAddTuple clicked() Dialog addRow() 124 155 197 158 cmdRemoveTuple clicked() Dialog deleteRow() 122 181 182 193 addColumn() addRow() deleteColumn() deleteRow() relational/relational_gui/surveyForm.py0000644000175100017510000002063712257142102020001 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli try: from PyQt4 import QtCore, QtGui except: from PySide import QtCore, QtGui import compatibility from relational import maintenance import platform import locale class surveyForm (QtGui.QWidget): '''This class is the form used for the survey, needed to intercept the events. It also sends the data with http POST to a page''' def setUi(self, ui): self.ui = ui def setDefaultValues(self): '''Sets default values into the form GUI. It has to be called after the form has been initialized''' # Dictionary with country codes countries = {'BD': 'BANGLADESH', 'BE': 'BELGIUM', 'BF': 'BURKINA FASO', 'BG': 'BULGARIA', 'BA': 'BOSNIA AND HERZEGOVINA', 'BB': 'BARBADOS', 'WF': 'WALLIS AND FUTUNA', 'BL': 'SAINT BARTH\xc3\x89LEMY', 'BM': 'BERMUDA', 'BN': 'BRUNEI DARUSSALAM', 'BO': 'BOLIVIA, PLURINATIONAL STATE OF', 'BH': 'BAHRAIN', 'BI': 'BURUNDI', 'BJ': 'BENIN', 'BT': 'BHUTAN', 'JM': 'JAMAICA', 'BV': 'BOUVET ISLAND', 'BW': 'BOTSWANA', 'WS': 'SAMOA', 'BR': 'BRAZIL', 'BS': 'BAHAMAS', 'JE': 'JERSEY', 'BY': 'BELARUS', 'BZ': 'BELIZE', 'RU': 'RUSSIAN FEDERATION', 'RW': 'RWANDA', 'RS': 'SERBIA', 'TL': 'TIMOR-LESTE', 'RE': 'R\xc3\x89UNION', 'TM': 'TURKMENISTAN', 'TJ': 'TAJIKISTAN', 'RO': 'ROMANIA', 'TK': 'TOKELAU', 'GW': 'GUINEA-BISSAU', 'GU': 'GUAM', 'GT': 'GUATEMALA', 'GS': 'SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS', 'GR': 'GREECE', 'GQ': 'EQUATORIAL GUINEA', 'GP': 'GUADELOUPE', 'JP': 'JAPAN', 'GY': 'GUYANA', 'GG': 'GUERNSEY', 'GF': 'FRENCH GUIANA', 'GE': 'GEORGIA', 'GD': 'GRENADA', 'GB': 'UNITED KINGDOM', 'GA': 'GABON', 'GN': 'GUINEA', 'GM': 'GAMBIA', 'GL': 'GREENLAND', 'GI': 'GIBRALTAR', 'GH': 'GHANA', 'OM': 'OMAN', 'TN': 'TUNISIA', 'JO': 'JORDAN', 'HR': 'CROATIA', 'HT': 'HAITI', 'HU': 'HUNGARY', 'HK': 'HONG KONG', 'HN': 'HONDURAS', 'HM': 'HEARD ISLAND AND MCDONALD ISLANDS', 'VE': 'VENEZUELA, BOLIVARIAN REPUBLIC OF', 'PR': 'PUERTO RICO', 'PS': 'PALESTINIAN TERRITORY, OCCUPIED', 'PW': 'PALAU', 'PT': 'PORTUGAL', 'KN': 'SAINT KITTS AND NEVIS', 'PY': 'PARAGUAY', 'IQ': 'IRAQ', 'PA': 'PANAMA', 'PF': 'FRENCH POLYNESIA', 'PG': 'PAPUA NEW GUINEA', 'PE': 'PERU', 'PK': 'PAKISTAN', 'PH': 'PHILIPPINES', 'PN': 'PITCAIRN', 'PL': 'POLAND', 'PM': 'SAINT PIERRE AND MIQUELON', 'ZM': 'ZAMBIA', 'EH': 'WESTERN SAHARA', 'EE': 'ESTONIA', 'EG': 'EGYPT', 'ZA': 'SOUTH AFRICA', 'EC': 'ECUADOR', 'IT': 'ITALY', 'VN': 'VIET NAM', 'SB': 'SOLOMON ISLANDS', 'ET': 'ETHIOPIA', 'SO': 'SOMALIA', 'ZW': 'ZIMBABWE', 'SA': 'SAUDI ARABIA', 'ES': 'SPAIN', 'ER': 'ERITREA', 'ME': 'MONTENEGRO', 'MD': 'MOLDOVA, REPUBLIC OF', 'MG': 'MADAGASCAR', 'MF': 'SAINT MARTIN', 'MA': 'MOROCCO', 'MC': 'MONACO', 'UZ': 'UZBEKISTAN', 'MM': 'MYANMAR', 'ML': 'MALI', 'MO': 'MACAO', 'MN': 'MONGOLIA', 'MH': 'MARSHALL ISLANDS', 'MK': 'MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF', 'MU': 'MAURITIUS', 'MT': 'MALTA', 'MW': 'MALAWI', 'MV': 'MALDIVES', 'MQ': 'MARTINIQUE', 'MP': 'NORTHERN MARIANA ISLANDS', 'MS': 'MONTSERRAT', 'MR': 'MAURITANIA', 'IM': 'ISLE OF MAN', 'UG': 'UGANDA', 'TZ': 'TANZANIA, UNITED REPUBLIC OF', 'MY': 'MALAYSIA', 'MX': 'MEXICO', 'IL': 'ISRAEL', 'FR': 'FRANCE', 'AW': 'ARUBA', 'SH': 'SAINT HELENA', 'SJ': 'SVALBARD AND JAN MAYEN', 'FI': 'FINLAND', 'FJ': 'FIJI', 'FK': 'FALKLAND ISLANDS (MALVINAS)', 'FM': 'MICRONESIA, FEDERATED STATES OF', 'FO': 'FAROE ISLANDS', 'NI': 'NICARAGUA', 'NL': 'NETHERLANDS', 'NO': 'NORWAY', 'NA': 'NAMIBIA', 'VU': 'VANUATU', 'NC': 'NEW CALEDONIA', 'NE': 'NIGER', 'NF': 'NORFOLK ISLAND', 'NG': 'NIGERIA', 'NZ': 'NEW ZEALAND', 'NP': 'NEPAL', 'NR': 'NAURU', 'NU': 'NIUE', 'CK': 'COOK ISLANDS', 'CI': "C\xc3\x94TE D'IVOIRE", 'CH': 'SWITZERLAND', 'CO': 'COLOMBIA', 'CN': 'CHINA', 'CM': 'CAMEROON', 'CL': 'CHILE', 'CC': 'COCOS (KEELING) ISLANDS', 'CA': 'CANADA', 'CG': 'CONGO', 'CF': 'CENTRAL AFRICAN REPUBLIC', 'CD': 'CONGO, THE DEMOCRATIC REPUBLIC OF THE', 'CZ': 'CZECH REPUBLIC', 'CY': 'CYPRUS', 'CX': 'CHRISTMAS ISLAND', 'CR': 'COSTA RICA', 'CV': 'CAPE VERDE', 'CU': 'CUBA', 'SZ': 'SWAZILAND', 'SY': 'SYRIAN ARAB REPUBLIC', 'KG': 'KYRGYZSTAN', 'KE': 'KENYA', 'SR': 'SURINAME', 'KI': 'KIRIBATI', 'KH': 'CAMBODIA', 'SV': 'EL SALVADOR', 'KM': 'COMOROS', 'ST': 'SAO TOME AND PRINCIPE', 'SK': 'SLOVAKIA', 'KR': 'KOREA, REPUBLIC OF', 'SI': 'SLOVENIA', 'KP': "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF", 'KW': 'KUWAIT', 'SN': 'SENEGAL', 'SM': 'SAN MARINO', 'SL': 'SIERRA LEONE', 'SC': 'SEYCHELLES', 'KZ': 'KAZAKHSTAN', 'KY': 'CAYMAN ISLANDS', 'SG': 'SINGAPORE', 'SE': 'SWEDEN', 'SD': 'SUDAN', 'DO': 'DOMINICAN REPUBLIC', 'DM': 'DOMINICA', 'DJ': 'DJIBOUTI', 'DK': 'DENMARK', 'VG': 'VIRGIN ISLANDS, BRITISH', 'DE': 'GERMANY', 'YE': 'YEMEN', 'DZ': 'ALGERIA', 'US': 'UNITED STATES', 'UY': 'URUGUAY', 'YT': 'MAYOTTE', 'UM': 'UNITED STATES MINOR OUTLYING ISLANDS', 'LB': 'LEBANON', 'LC': 'SAINT LUCIA', 'LA': "LAO PEOPLE'S DEMOCRATIC REPUBLIC", 'TV': 'TUVALU', 'TW': 'TAIWAN, PROVINCE OF CHINA', 'TT': 'TRINIDAD AND TOBAGO', 'TR': 'TURKEY', 'LK': 'SRI LANKA', 'LI': 'LIECHTENSTEIN', 'LV': 'LATVIA', 'TO': 'TONGA', 'LT': 'LITHUANIA', 'LU': 'LUXEMBOURG', 'LR': 'LIBERIA', 'LS': 'LESOTHO', 'TH': 'THAILAND', 'TF': 'FRENCH SOUTHERN TERRITORIES', 'TG': 'TOGO', 'TD': 'CHAD', 'TC': 'TURKS AND CAICOS ISLANDS', 'LY': 'LIBYAN ARAB JAMAHIRIYA', 'VA': 'HOLY SEE (VATICAN CITY STATE)', 'VC': 'SAINT VINCENT AND THE GRENADINES', 'AE': 'UNITED ARAB EMIRATES', 'AD': 'ANDORRA', 'AG': 'ANTIGUA AND BARBUDA', 'AF': 'AFGHANISTAN', 'AI': 'ANGUILLA', 'VI': 'VIRGIN ISLANDS, U.S.', 'IS': 'ICELAND', 'IR': 'IRAN, ISLAMIC REPUBLIC OF', 'AM': 'ARMENIA', 'AL': 'ALBANIA', 'AO': 'ANGOLA', 'AN': 'NETHERLANDS ANTILLES', 'AQ': 'ANTARCTICA', 'AS': 'AMERICAN SAMOA', 'AR': 'ARGENTINA', 'AU': 'AUSTRALIA', 'AT': 'AUSTRIA', 'IO': 'BRITISH INDIAN OCEAN TERRITORY', 'IN': 'INDIA', 'AX': '\xc3\x85LAND ISLANDS', 'AZ': 'AZERBAIJAN', 'IE': 'IRELAND', 'ID': 'INDONESIA', 'UA': 'UKRAINE', 'QA': 'QATAR', 'MZ': 'MOZAMBIQUE'} # Setting system string try: self.ui.txtSystem.setText(platform.platform()) self.ui.txtSystem.setCursorPosition(0) except: pass # Getting country from locale code try: locale.setlocale(locale.LC_ALL, '') country_code = locale.getlocale()[0].split('_')[1] self.ui.txtCountry.setText(countries[country_code]) self.ui.txtCountry.setCursorPosition(0) except: pass def send(self): '''Sends the data inserted in the form''' post = {} post['software'] = "Relational algebra" post["version"] = version post["system"] = compatibility.get_py_str(self.ui.txtSystem.text()) post["country"] = compatibility.get_py_str(self.ui.txtCountry.text()) post["school"] = compatibility.get_py_str(self.ui.txtSchool.text()) post["age"] = compatibility.get_py_str(self.ui.txtAge.text()) post["find"] = compatibility.get_py_str(self.ui.txtFind.text()) post["email"] = compatibility.get_py_str(self.ui.txtEmail.text()) post["comments"] = compatibility.get_py_str( self.ui.txtComments.toPlainText()) # Clears the form self.ui.txtSystem.clear() self.ui.txtCountry.clear() self.ui.txtSchool.clear() self.ui.txtAge.clear() self.ui.txtFind.clear() self.ui.txtEmail.clear() self.ui.txtComments.clear() response = maintenance.send_survey(post) if response.status != 200: QtGui.QMessageBox.information(None, QtGui.QApplication.translate( "Form", "Error"), QtGui.QApplication.translate("Form", "Unable to send the data!")) else: QtGui.QMessageBox.information(None, QtGui.QApplication.translate( "Form", "Thanks"), QtGui.QApplication.translate("Form", "Thanks for sending!")) self.hide() relational/relational_gui/guihandler.py0000644000175100017510000003101612257142102017733 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli import sys import os import pickle try: from PyQt4 import QtCore, QtGui except: from PySide import QtCore, QtGui from relational import relation, parser, optimizer, rtypes import about import survey import surveyForm import maingui import compatibility class relForm(QtGui.QMainWindow): def __init__(self, ui): QtGui.QMainWindow.__init__(self) self.About = None self.Survey = None self.relations = {} # Dictionary for relations self.undo = None # UndoQueue for queries self.selectedRelation = None self.ui = ui self.qcounter = 1 # Query counter self.settings = QtCore.QSettings() def checkVersion(self): from relational import maintenance online = maintenance.check_latest_version() if online > version: r = QtGui.QApplication.translate( "Form", "New version available online: %s." % online) elif online == version: r = QtGui.QApplication.translate( "Form", "Latest version installed.") else: r = QtGui.QApplication.translate( "Form", "You are using an unstable version.") QtGui.QMessageBox.information( self, QtGui.QApplication.translate("Form", "Version"), r) def load_query(self, *index): self.ui.txtQuery.setText(self.savedQ.itemData(index[0]).toString()) def undoOptimize(self): '''Undoes the optimization on the query, popping one item from the undo list''' if self.undo != None: self.ui.txtQuery.setText(self.undo) def optimize(self): '''Performs all the possible optimizations on the query''' self.undo = self.ui.txtQuery.text() # Storing the query in undo list query = compatibility.get_py_str(self.ui.txtQuery.text()) try: result = optimizer.optimize_all(query, self.relations) compatibility.set_utf8_text(self.ui.txtQuery, result) except Exception, e: QtGui.QMessageBox.information(None, QtGui.QApplication.translate("Form", "Error"), "%s\n%s" % (QtGui.QApplication.translate("Form", "Check your query!"), e.__str__())) def resumeHistory(self, item): itm = compatibility.get_py_str(item.text()).split(' = ', 1) compatibility.set_utf8_text(self.ui.txtResult, itm[0]) compatibility.set_utf8_text(self.ui.txtQuery, itm[1]) def execute(self): '''Executes the query''' query = compatibility.get_py_str(self.ui.txtQuery.text()) res_rel = compatibility.get_py_str( self.ui.txtResult.text()) # result relation's name if not rtypes.is_valid_relation_name(res_rel): QtGui.QMessageBox.information(self, QtGui.QApplication.translate( "Form", "Error"), QtGui.QApplication.translate("Form", "Wrong name for destination relation.")) return try: # Converting string to utf8 and then from qstring to normal string expr = parser.parse(query) # Converting expression to python code print query, "-->", expr # Printing debug result = eval(expr, self.relations) # Evaluating the expression self.relations[ res_rel] = result # Add the relation to the dictionary self.updateRelations() # update the list self.selectedRelation = result self.showRelation(self.selectedRelation) # Show the result in the table except Exception, e: print e.__unicode__() QtGui.QMessageBox.information(None, QtGui.QApplication.translate("Form", "Error"), u"%s\n%s" % (QtGui.QApplication.translate("Form", "Check your query!"), e.__unicode__())) return # Adds to history item = u'%s = %s' % (compatibility.get_py_str( self.ui.txtResult.text()), compatibility.get_py_str(self.ui.txtQuery.text())) # item=item.decode('utf-8')) compatibility.add_list_item(self.ui.lstHistory, item) self.qcounter += 1 compatibility.set_utf8_text(self.ui.txtResult, u"_last%d" % self.qcounter) # Sets the result relation name to none def showRelation(self, rel): '''Shows the selected relation into the table''' self.ui.table.clear() if rel == None: # No relation to show self.ui.table.setColumnCount(1) self.ui.table.headerItem().setText(0, "Empty relation") return self.ui.table.setColumnCount(len(rel.header.attributes)) # Set content for i in rel.content: item = QtGui.QTreeWidgetItem() for j in range(len(i)): item.setText(j, i[j]) self.ui.table.addTopLevelItem(item) # Sets columns for i in range(len(rel.header.attributes)): self.ui.table.headerItem().setText(i, rel.header.attributes[i]) self.ui.table.resizeColumnToContents( i) # Must be done in order to avoid too small columns def printRelation(self, item): self.selectedRelation = self.relations[ compatibility.get_py_str(item.text())] self.showRelation(self.selectedRelation) def showAttributes(self, item): '''Shows the attributes of the selected relation''' rel = compatibility.get_py_str(item.text()) self.ui.lstAttributes.clear() for j in self.relations[rel].header.attributes: self.ui.lstAttributes.addItem(j) def updateRelations(self): self.ui.lstRelations.clear() for i in self.relations: if i != "__builtins__": self.ui.lstRelations.addItem(i) def saveRelation(self): filename = QtGui.QFileDialog.getSaveFileName(self, QtGui.QApplication.translate( "Form", "Save Relation"), "", QtGui.QApplication.translate("Form", "Relations (*.csv)")) filename = compatibility.get_filename(filename) if (len(filename) == 0): # Returns if no file was selected return self.selectedRelation.save(filename) return def unloadRelation(self): for i in self.ui.lstRelations.selectedItems(): del self.relations[compatibility.get_py_str(i.text())] self.updateRelations() def editRelation(self): import creator for i in self.ui.lstRelations.selectedItems(): result = creator.edit_relation( self.relations[compatibility.get_py_str(i.text())]) if result != None: self.relations[compatibility.get_py_str(i.text())] = result self.updateRelations() def newRelation(self): import creator result = creator.edit_relation() if result == None: return res = QtGui.QInputDialog.getText( self, QtGui.QApplication.translate("Form", "New relation"), QtGui.QApplication.translate( "Form", "Insert the name for the new relation"), QtGui.QLineEdit.Normal, '') if res[1] == False or len(res[0]) == 0: return # Patch provided by Angelo 'Havoc' Puglisi name = compatibility.get_py_str(res[0]) if not rtypes.is_valid_relation_name(name): r = QtGui.QApplication.translate( "Form", str("Wrong name for destination relation: %s." % name)) QtGui.QMessageBox.information( self, QtGui.QApplication.translate("Form", "Error"), r) return try: self.relations[name] = result except Exception, e: print e QtGui.QMessageBox.information(None, QtGui.QApplication.translate("Form", "Error"), "%s\n%s" % (QtGui.QApplication.translate("Form", "Check your query!"), e.__str__())) return self.updateRelations() def closeEvent(self, event): self.save_settings() event.accept() def save_settings(self): # self.settings.setValue("width",) pass def restore_settings(self): # self.settings.value('session_name','default').toString() pass def showSurvey(self): if self.Survey == None: self.Survey = surveyForm.surveyForm() ui = survey.Ui_Form() self.Survey.setUi(ui) ui.setupUi(self.Survey) self.Survey.setDefaultValues() self.Survey.show() def showAbout(self): if self.About == None: self.About = QtGui.QDialog() ui = about.Ui_Dialog() ui.setupUi(self.About) self.About.show() def loadRelation(self, filename=None, name=None): '''Loads a relation. Without parameters it will ask the user which relation to load, otherwise it will load filename, giving it name. It shouldn't be called giving filename but not giving name.''' # Asking for file to load if filename == None: filename = QtGui.QFileDialog.getOpenFileName(self, QtGui.QApplication.translate( "Form", "Load Relation"), "", QtGui.QApplication.translate("Form", "Relations (*.csv);;Text Files (*.txt);;All Files (*)")) filename = compatibility.get_filename(filename) # Default relation's name f = filename.split('/') # Split the full path defname = f[len(f) - 1].lower() # Takes only the lowercase filename if len(defname) == 0: return if (defname.endswith(".csv")): # removes the extension defname = defname[:-4] if name == None: # Prompt dialog to insert name for the relation res = QtGui.QInputDialog.getText( self, QtGui.QApplication.translate("Form", "New relation"), QtGui.QApplication.translate( "Form", "Insert the name for the new relation"), QtGui.QLineEdit.Normal, defname) if res[1] == False or len(res[0]) == 0: return # Patch provided by Angelo 'Havoc' Puglisi name = compatibility.get_py_str(res[0]) if not rtypes.is_valid_relation_name(name): r = QtGui.QApplication.translate( "Form", str("Wrong name for destination relation: %s." % name)) QtGui.QMessageBox.information( self, QtGui.QApplication.translate("Form", "Error"), r) return try: self.relations[name] = relation.relation(filename) except Exception, e: print e QtGui.QMessageBox.information(None, QtGui.QApplication.translate("Form", "Error"), "%s\n%s" % (QtGui.QApplication.translate("Form", "Check your query!"), e.__str__())) return self.updateRelations() def addProduct(self): self.addSymbolInQuery(u"*") def addDifference(self): self.addSymbolInQuery(u"-") def addUnion(self): self.addSymbolInQuery(u"ᑌ") def addIntersection(self): self.addSymbolInQuery(u"ᑎ") def addDivision(self): self.addSymbolInQuery(u"÷") def addOLeft(self): self.addSymbolInQuery(u"ᐅLEFTᐊ") def addJoin(self): self.addSymbolInQuery(u"ᐅᐊ") def addORight(self): self.addSymbolInQuery(u"ᐅRIGHTᐊ") def addOuter(self): self.addSymbolInQuery(u"ᐅFULLᐊ") def addProjection(self): self.addSymbolInQuery(u"π") def addSelection(self): self.addSymbolInQuery(u"σ") def addRename(self): self.addSymbolInQuery(u"ρ") def addArrow(self): self.addSymbolInQuery(u"➡") def addSymbolInQuery(self, symbol): self.ui.txtQuery.insert(symbol) self.ui.txtQuery.setFocus() relational/relational_gui/creator.py0000644000175100017510000001161712257142102017255 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli try: from PyQt4 import QtCore, QtGui except: from PySide import QtCore, QtGui import compatibility from relational import relation import rel_edit class creatorForm(QtGui.QDialog): def __init__(self, rel=None): QtGui.QDialog.__init__(self) self.setSizeGripEnabled(True) self.result_relation = None self.rel = rel def setUi(self, ui): self.ui = ui self.table = self.ui.table if self.rel == None: self.setup_empty() else: self.setup_relation(self.rel) def setup_relation(self, rel): self.table.insertRow(0) for i in rel.header.attributes: item = QtGui.QTableWidgetItem() item.setText(i) self.table.insertColumn(self.table.columnCount()) self.table.setItem(0, self.table.columnCount() - 1, item) for i in rel.content: self.table.insertRow(self.table.rowCount()) for j in range(len(i)): item = QtGui.QTableWidgetItem() item.setText(i[j]) self.table.setItem(self.table.rowCount() - 1, j, item) pass def setup_empty(self): self.table.insertColumn(0) self.table.insertColumn(0) self.table.insertRow(0) self.table.insertRow(0) i00 = QtGui.QTableWidgetItem() i01 = QtGui.QTableWidgetItem() i10 = QtGui.QTableWidgetItem() i11 = QtGui.QTableWidgetItem() i00.setText('Field name 1') i01.setText('Field name 2') i10.setText('Value 1') i11.setText('Value 2') self.table.setItem(0, 0, i00) self.table.setItem(0, 1, i01) self.table.setItem(1, 0, i10) self.table.setItem(1, 1, i11) def create_relation(self): hlist = [] for i in range(self.table.columnCount()): hlist.append( compatibility.get_py_str(self.table.item(0, i).text())) try: header = relation.header(hlist) except Exception, e: QtGui.QMessageBox.information(None, QtGui.QApplication.translate("Form", "Error"), "%s\n%s" % ( QtGui.QApplication.translate("Form", "Header error!"), e.__str__())) return None r = relation.relation() r.header = header for i in range(1, self.table.rowCount()): hlist = [] for j in range(self.table.columnCount()): try: hlist.append( compatibility.get_py_str(self.table.item(i, j).text())) except: QtGui.QMessageBox.information(None, QtGui.QApplication.translate( "Form", "Error"), QtGui.QApplication.translate("Form", "Unset value in %d,%d!" % (i + 1, j + 1))) return None r.content.add(tuple(hlist)) return r def accept(self): self.result_relation = self.create_relation() # Doesn't close the window in case of errors if self.result_relation != None: QtGui.QDialog.accept(self) pass def reject(self): self.result_relation = None QtGui.QDialog.reject(self) pass def addColumn(self): self.table.insertColumn(self.table.columnCount()) pass def addRow(self): self.table.insertRow(1) pass def deleteColumn(self): if self.table.columnCount() > 1: self.table.removeColumn(self.table.currentColumn()) pass def deleteRow(self): if self.table.rowCount() > 2: self.table.removeRow(self.table.currentRow()) pass def edit_relation(rel=None): '''Opens the editor for the given relation and returns a _new_ relation containing the new relation. If the user cancels, it returns None''' ui = rel_edit.Ui_Dialog() Form = creatorForm(rel) ui.setupUi(Form) Form.setUi(ui) Form.exec_() return Form.result_relation if __name__ == '__main__': import sys app = QtGui.QApplication(sys.argv) r = relation.relation( "/home/salvo/dev/relational/trunk/samples/people.csv") print edit_relation(r) relational/relational_gui/rel_edit.py0000644000175100017510000001026312257142102017401 0ustar salvosalvo# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'relational_gui/rel_edit.ui' # # Created: Fri Dec 27 00:23:51 2013 # by: PyQt4 UI code generator 4.10.3 # # WARNING! All changes made in this file will be lost! from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s try: _encoding = QtGui.QApplication.UnicodeUTF8 def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName(_fromUtf8("Dialog")) Dialog.resize(594, 444) self.verticalLayout_2 = QtGui.QVBoxLayout(Dialog) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.groupBox = QtGui.QGroupBox(Dialog) self.groupBox.setObjectName(_fromUtf8("groupBox")) self.verticalLayout = QtGui.QVBoxLayout(self.groupBox) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.cmdAddTuple = QtGui.QPushButton(self.groupBox) self.cmdAddTuple.setObjectName(_fromUtf8("cmdAddTuple")) self.verticalLayout.addWidget(self.cmdAddTuple) self.cmdRemoveTuple = QtGui.QPushButton(self.groupBox) self.cmdRemoveTuple.setObjectName(_fromUtf8("cmdRemoveTuple")) self.verticalLayout.addWidget(self.cmdRemoveTuple) self.cmdAddColumn = QtGui.QPushButton(self.groupBox) self.cmdAddColumn.setObjectName(_fromUtf8("cmdAddColumn")) self.verticalLayout.addWidget(self.cmdAddColumn) self.cmdRemoveColumn = QtGui.QPushButton(self.groupBox) self.cmdRemoveColumn.setObjectName(_fromUtf8("cmdRemoveColumn")) self.verticalLayout.addWidget(self.cmdRemoveColumn) self.horizontalLayout.addWidget(self.groupBox) self.table = QtGui.QTableWidget(Dialog) self.table.setObjectName(_fromUtf8("table")) self.table.setColumnCount(0) self.table.setRowCount(0) self.horizontalLayout.addWidget(self.table) self.verticalLayout_2.addLayout(self.horizontalLayout) self.label = QtGui.QLabel(Dialog) self.label.setObjectName(_fromUtf8("label")) self.verticalLayout_2.addWidget(self.label) self.buttonBox = QtGui.QDialogButtonBox(Dialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.verticalLayout_2.addWidget(self.buttonBox) self.retranslateUi(Dialog) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject) QtCore.QObject.connect(self.cmdAddColumn, QtCore.SIGNAL(_fromUtf8("clicked()")), Dialog.addColumn) QtCore.QObject.connect(self.cmdRemoveColumn, QtCore.SIGNAL(_fromUtf8("clicked()")), Dialog.deleteColumn) QtCore.QObject.connect(self.cmdAddTuple, QtCore.SIGNAL(_fromUtf8("clicked()")), Dialog.addRow) QtCore.QObject.connect(self.cmdRemoveTuple, QtCore.SIGNAL(_fromUtf8("clicked()")), Dialog.deleteRow) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): Dialog.setWindowTitle(_translate("Dialog", "Relation editor", None)) self.groupBox.setTitle(_translate("Dialog", "Edit", None)) self.cmdAddTuple.setText(_translate("Dialog", "Add tuple", None)) self.cmdRemoveTuple.setText(_translate("Dialog", "Remove tuple", None)) self.cmdAddColumn.setText(_translate("Dialog", "Add column", None)) self.cmdRemoveColumn.setText(_translate("Dialog", "Remove column", None)) self.label.setText(_translate("Dialog", "Remember that new relations and modified relations are not automatically saved", None)) relational/relational_gui/compatibility.py0000644000175100017510000000337112257142102020465 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2011 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli # # Module to unify the use of both pyqt and pyside try: from PyQt4 import QtCore, QtGui pyqt = True except: from PySide import QtCore, QtGui pyqt = False def get_py_str(a): '''Returns a python string out of a QString''' if pyqt: return unicode(a.toUtf8(), 'utf-8') return a # Already a python string in PySide def set_utf8_text(component, text): if not pyqt: component.setText(text) else: component.setText(QtCore.QString.fromUtf8(text)) def get_filename(filename): if pyqt: return str(filename.toUtf8()) return filename[0] def add_list_item(l, item): if pyqt: history_item = QtCore.QString() history_item.append(item) hitem = QtGui.QListWidgetItem(None, 0) hitem.setText(history_item) l.addItem(hitem) l.setCurrentItem(hitem) else: hitem = QtGui.QListWidgetItem(None, 0) hitem.setText(item) l.addItem(hitem) l.setCurrentItem(hitem) relational/relational_gui/maingui.ui0000644000175100017510000007672712257142102017251 0ustar salvosalvo Salvo 'LtWorf' Tomaselli MainWindow 0 0 800 612 Relational Qt::Horizontal Menu About Survey Operators Product * Difference - Union Intersection Division ÷ Natural join ᐅᐊ Left outer join ᐅLEFTᐊ Right outer join ᐅRIGHTᐊ Full outer join ᐅFULLᐊ Projection π Selection σ Rename ρ Qt::Vertical 20 25 Qt::Horizontal Qt::Vertical 450 400 0 0 false Empty relation QLayout::SetMinimumSize 0 0 16777215 16777215 0 0 false Optimize Undo optimize Clear history Qt::Vertical 0 0 300 16777215 Relations 0 0 16777215 16777215 true New relation Load relation Save relation Edit relation Unload relation 0 0 300 16777215 Attributes 0 0 16777215 16777215 0 0 _last1 = txtQuery Execute 0 0 800 19 &File &Help Relations &About QAction::AboutRole &Load relation Ctrl+O &Save relation Ctrl+S &Quit Ctrl+Q QAction::QuitRole Check for new versions New relation Ctrl+N Edit relation Ctrl+E New session Save session as Save session as Manage sessions Unload relation cmdAbout cmdSurvey cmdProduct cmdDifference cmdUnion cmdIntersection cmdDivision cmdJoin cmdOuterLeft cmdOuterRight cmdOuter cmdProjection cmdSelection cmdRename cmdArrow table lstHistory cmdOptimize cmdUndoOptimize cmdClearHistory lstRelations cmdLoad cmdSave cmdUnload lstAttributes txtResult txtQuery cmdClearQuery cmdExecute cmdClearQuery clicked() txtQuery clear() 686 591 206 591 cmdClearHistory clicked() lstHistory clear() 490 563 397 525 txtQuery returnPressed() MainWindow execute() 450 599 438 611 cmdExecute clicked() MainWindow execute() 732 592 592 611 cmdAbout clicked() MainWindow showAbout() 82 75 79 597 cmdSurvey clicked() MainWindow showSurvey() 63 96 99 605 cmdProduct clicked() MainWindow addProduct() 53 166 180 611 cmdDifference clicked() MainWindow addDifference() 94 193 46 611 cmdArrow clicked() MainWindow addArrow() 107 490 58 608 cmdRename clicked() MainWindow addRename() 54 463 111 611 cmdSelection clicked() MainWindow addSelection() 84 436 16 611 cmdProjection clicked() MainWindow addProjection() 107 409 91 597 cmdUnload clicked() MainWindow unloadRelation() 788 280 773 599 cmdSave clicked() MainWindow saveRelation() 788 253 760 610 cmdLoad clicked() MainWindow loadRelation() 788 226 753 594 cmdOptimize clicked() MainWindow optimize() 245 554 684 611 cmdUndoOptimize clicked() MainWindow undoOptimize() 336 560 652 604 txtResult returnPressed() txtQuery setFocus() 87 590 182 590 cmdOuterRight clicked() MainWindow addORight() 102 355 58 611 cmdOuter clicked() MainWindow addOuter() 46 382 86 611 cmdOuterLeft clicked() MainWindow addOLeft() 44 328 66 611 cmdJoin clicked() MainWindow addJoin() 107 301 147 611 cmdDivision clicked() MainWindow addDivision() 71 272 185 611 cmdIntersection clicked() MainWindow addIntersection() 99 244 228 611 cmdUnion clicked() MainWindow addUnion() 32 220 279 611 lstRelations itemDoubleClicked(QListWidgetItem*) MainWindow printRelation(QListWidgetItem*) 708 110 643 611 lstRelations itemClicked(QListWidgetItem*) MainWindow showAttributes(QListWidgetItem*) 615 182 510 611 cmdClearQuery clicked() txtQuery setFocus() 693 599 588 597 lstHistory itemDoubleClicked(QListWidgetItem*) MainWindow resumeHistory(QListWidgetItem*) 349 492 399 305 actionAbout triggered() MainWindow showAbout() -1 -1 399 305 action_Load_relation triggered() MainWindow loadRelation() -1 -1 399 305 action_Save_relation triggered() MainWindow saveRelation() -1 -1 399 305 action_Quit triggered() MainWindow close() -1 -1 399 305 actionCheck_for_new_versions triggered() MainWindow checkVersion() -1 -1 399 305 cmdEdit clicked() MainWindow editRelation() 683 323 399 305 actionEdit_relation triggered() MainWindow editRelation() -1 -1 399 305 cmdNew clicked() MainWindow newRelation() 683 296 399 305 actionNew_relation triggered() MainWindow newRelation() -1 -1 399 305 actionUnload_relation triggered() MainWindow unloadRelation() -1 -1 399 305 execute() checkVersion() showAbout() showSurvey() addProduct() addDifference() addUnion() addIntersection() addDivision() addOLeft() addORight() addOuter() addJoin() addProjection() addSelection() addRename() addArrow() optimize() undoOptimize() loadRelation() unloadRelation() saveRelation() insertTuple() deleteTuple() printRelation(QListWidgetItem*) showAttributes(QListWidgetItem*) loadQuery() resumeHistory(QListWidgetItem*) editRelation() newRelation() newSession() saveSessionAs() manageSessions() relational/relational_gui/about.py0000644000175100017510000022061712257142102016732 0ustar salvosalvo# -*- coding: utf-8 -*- # Relational # Copyright (C) 2008 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # author Salvo "LtWorf" Tomaselli import os try: from PyQt4 import QtCore, QtGui try: # If QtWebKit is available, uses it from PyQt4 import QtWebKit webk = True except: webk = False except: from PySide import QtCore, QtGui try: # If QtWebKit is available, uses it from PySide import QtWebKit webk = True except: webk = False version = 0 class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(510, 453) self.verticalLayout_2 = QtGui.QVBoxLayout(Dialog) self.verticalLayout_2.setObjectName("verticalLayout_2") self.tabWidget = QtGui.QTabWidget(Dialog) self.tabWidget.setObjectName("tabWidget") self.tab = QtGui.QWidget() self.tab.setGeometry(QtCore.QRect(0, 0, 494, 377)) self.tab.setObjectName("tab") self.verticalLayout_3 = QtGui.QVBoxLayout(self.tab) self.verticalLayout_3.setObjectName("verticalLayout_3") self.groupBox = QtGui.QGroupBox(self.tab) self.groupBox.setObjectName("groupBox") self.verticalLayout_5 = QtGui.QVBoxLayout(self.groupBox) self.verticalLayout_5.setObjectName("verticalLayout_5") self.label = QtGui.QLabel(self.groupBox) font = QtGui.QFont() font.setPointSize(15) self.label.setFont(font) self.label.setObjectName("label") self.verticalLayout_5.addWidget(self.label) self.label_3 = QtGui.QLabel(self.groupBox) self.label_3.setObjectName("label_3") self.verticalLayout_5.addWidget(self.label_3) self.verticalLayout_3.addWidget(self.groupBox) self.groupBox_3 = QtGui.QGroupBox(self.tab) self.groupBox_3.setObjectName("groupBox_3") self.verticalLayout_4 = QtGui.QVBoxLayout(self.groupBox_3) self.verticalLayout_4.setObjectName("verticalLayout_4") self.label_2 = QtGui.QLabel(self.groupBox_3) self.label_2.setObjectName("label_2") self.verticalLayout_4.addWidget(self.label_2) self.verticalLayout_3.addWidget(self.groupBox_3) self.groupBox_2 = QtGui.QGroupBox(self.tab) self.groupBox_2.setObjectName("groupBox_2") self.verticalLayout_6 = QtGui.QVBoxLayout(self.groupBox_2) self.verticalLayout_6.setObjectName("verticalLayout_6") self.label_4 = QtGui.QLabel(self.groupBox_2) self.label_4.setObjectName("label_4") self.verticalLayout_6.addWidget(self.label_4) self.verticalLayout_3.addWidget(self.groupBox_2) self.tabWidget.addTab(self.tab, "") self.License = QtGui.QWidget() self.License.setGeometry(QtCore.QRect(0, 0, 494, 377)) self.License.setObjectName("License") self.verticalLayout = QtGui.QVBoxLayout(self.License) self.verticalLayout.setObjectName("verticalLayout") self.textEdit = QtGui.QTextEdit(self.License) self.textEdit.setObjectName("textEdit") self.verticalLayout.addWidget(self.textEdit) self.tabWidget.addTab(self.License, "") self.tab_2 = QtGui.QWidget() self.tab_2.setObjectName("tab_2") self.verticalLayout_7 = QtGui.QVBoxLayout(self.tab_2) self.verticalLayout_7.setObjectName("verticalLayout_7") if (webk): self.webView = QtWebKit.QWebView(self.tab_2) self.webView.setUrl( QtCore.QUrl("https://github.com/ltworf/relational/wiki/Grammar-and-language")) self.webView.setObjectName("webView") self.verticalLayout_7.addWidget(self.webView) else: self.webLink = QtGui.QLabel(self.groupBox) self.webLink.setFont(font) self.webLink.setObjectName("lblLink") self.webLink.setText(QtGui.QApplication.translate( "Dialog", "Relational's website", None,)) self.webLink.setOpenExternalLinks(True) self.webLink.setTextFormat(QtCore.Qt.AutoText) self.webLink.setTextInteractionFlags( QtCore.Qt.LinksAccessibleByKeyboard | QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextBrowserInteraction | QtCore.Qt.TextSelectableByKeyboard | QtCore.Qt.TextSelectableByMouse ) self.verticalLayout_7.addWidget(self.webLink) self.tabWidget.addTab(self.tab_2, "") self.verticalLayout_2.addWidget(self.tabWidget) self.buttonBox = QtGui.QDialogButtonBox(Dialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName("buttonBox") self.verticalLayout_2.addWidget(self.buttonBox) self.retranslateUi(Dialog) self.tabWidget.setCurrentIndex(0) QtCore.QObject.connect( self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept) QtCore.QObject.connect( self.buttonBox, QtCore.SIGNAL("rejected()"), Dialog.reject) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): Dialog.setWindowTitle(QtGui.QApplication.translate( "Dialog", "Documentation", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox.setTitle(QtGui.QApplication.translate( "Dialog", "Relational", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate( "Dialog", "Relational", None, QtGui.QApplication.UnicodeUTF8)) self.label_3.setText(QtGui.QApplication.translate( "Dialog", "Version " + version, None, QtGui.QApplication.UnicodeUTF8)) self.label_3.setTextInteractionFlags( QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextSelectableByMouse) self.groupBox_3.setTitle(QtGui.QApplication.translate( "Dialog", "Author", None, QtGui.QApplication.UnicodeUTF8)) self.label_2.setText(QtGui.QApplication.translate( "Dialog", "Salvo \"LtWorf\" Tomaselli <tiposchi@tiscali.it>
Emilio Di Prima <emiliodiprima[at]msn[dot]com> (For the windows setup)", None, QtGui.QApplication.UnicodeUTF8)) self.label_2.setOpenExternalLinks(True) self.label_2.setTextInteractionFlags( QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextSelectableByMouse) self.groupBox_2.setTitle(QtGui.QApplication.translate( "Dialog", "Links", None, QtGui.QApplication.UnicodeUTF8)) self.label_4.setText(QtGui.QApplication.translate( "Dialog", "https://github.com/ltworf/relational/", None, QtGui.QApplication.UnicodeUTF8)) self.label_4.setOpenExternalLinks(True) self.label_4.setTextInteractionFlags( QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextSelectableByMouse) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtGui.QApplication.translate( "Dialog", "About", None, QtGui.QApplication.UnicodeUTF8)) self.textEdit.setHtml(QtGui.QApplication.translate("Dialog", "\n" "GNU General Public License - GNU Project - Free Software Foundation (FSF)\n" "

GNU GENERAL PUBLIC LICENSE

\n" "

Version 3, 29 June 2007

\n" "

Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>

\n" "

Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

\n" "

Preamble

\n" "

The GNU General Public License is a free, copyleft license for software and other kinds of works.

\n" "

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.

\n" "

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.

\n" "

To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.

\n" "

For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

\n" "

Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

\n" "

For the developers\' and authors\' protection, the GPL clearly explains that there is no warranty for this free software. For both users\' and authors\' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.

\n" "

Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users\' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.

\n" "

Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.

\n" "

The precise terms and conditions for copying, distribution and modification follow.

\n" "

TERMS AND CONDITIONS

\n" "

0. Definitions.

\n" "

“This License” refers to version 3 of the GNU General Public License.

\n" "

“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.

\n" "

“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.

\n" "

To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.

\n" "

A “covered work” means either the unmodified Program or a work based on the Program.

\n" "

To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.

\n" "

To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.

\n" "

An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.

\n" "

1. Source Code.

\n" "

The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.

\n" "

A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.

\n" "

The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.

\n" "

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work\'s System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.

\n" "

The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.

\n" "

The Corresponding Source for a work in source code form is that same work.

\n" "

2. Basic Permissions.

\n" "

All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.

\n" "

You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.

\n" "

Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

\n" "

3. Protecting Users\' Legal Rights From Anti-Circumvention Law.

\n" "

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.

\n" "

When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work\'s users, your or third parties\' legal rights to forbid circumvention of technological measures.

\n" "

4. Conveying Verbatim Copies.

\n" "

You may convey verbatim copies of the Program\'s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.

\n" "

You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.

\n" "

5. Conveying Modified Source Versions.

\n" "

You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:

\n" "
  • a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
  • \n" "
  • b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
  • \n" "
  • c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
  • \n" "
  • d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
\n" "

A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation\'s users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

\n" "

6. Conveying Non-Source Forms.

\n" "

You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:

\n" "
  • a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
  • \n" "
  • b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
  • \n" "
  • c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
  • \n" "
  • d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
  • \n" "
  • e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
\n" "

A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.

\n" "

A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.

\n" "

“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.

\n" "

If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).

\n" "

The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.

\n" "

Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.

\n" "

7. Additional Terms.

\n" "

“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.

\n" "

When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.

\n" "

Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:

\n" "
  • a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
  • \n" "
  • b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
  • \n" "
  • c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
  • \n" "
  • d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
  • \n" "
  • e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
  • \n" "
  • f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
\n" "

All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.

\n" "

If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.

\n" "

Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.

\n" "

8. Termination.

\n" "

You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).

\n" "

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

\n" "

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

\n" "

Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.

\n" "

9. Acceptance Not Required for Having Copies.

\n" "

You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.

\n" "

10. Automatic Licensing of Downstream Recipients.

\n" "

Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.

\n" "

An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party\'s predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

\n" "

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.

\n" "

11. Patents.

\n" "

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor\'s “contributor version”.

\n" "

A contributor\'s “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.

\n" "

Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor\'s essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

\n" "

In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.

\n" "

If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient\'s use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

\n" "

If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.

\n" "

A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.

\n" "

Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

\n" "

12. No Surrender of Others\' Freedom.

\n" "

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.

\n" "

13. Use with the GNU Affero General Public License.

\n" "

Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.

\n" "

14. Revised Versions of this License.

\n" "

The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

\n" "

Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.

\n" "

If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy\'s public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

\n" "

Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.

\n" "

15. Disclaimer of Warranty.

\n" "

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

\n" "

16. Limitation of Liability.

\n" "

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

\n" "

17. Interpretation of Sections 15 and 16.

\n" "

If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.

\n" "

END OF TERMS AND CONDITIONS

\n" "

How to Apply These Terms to Your New Programs

\n" "

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

\n" "

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

\n" "
    <one line to give the program\'s name and a brief idea of what it does.>
\n" "
    Copyright (C) <year>  <name of author>
\n" "
\n"
                                                           "
    This program is free software: you can redistribute it and/or modify
\n" "
    it under the terms of the GNU General Public License as published by
\n" "
    the Free Software Foundation, either version 3 of the License, or
\n" "
    (at your option) any later version.
\n" "
\n"
                                                           "
    This program is distributed in the hope that it will be useful,
\n" "
    but WITHOUT ANY WARRANTY; without even the implied warranty of
\n" "
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
\n" "
    GNU General Public License for more details.
\n" "
\n"
                                                           "
    You should have received a copy of the GNU General Public License
\n" "
    along with this program.  If not, see <http://www.gnu.org/licenses/>. 
\n" "

Also add information on how to contact you by electronic and paper mail.

\n" "

If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:

\n" "
    <program>  Copyright (C) <year>  <name of author>
\n" "
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w\'.
\n" "
    This is free software, and you are welcome to redistribute it
\n" "
    under certain conditions; type `show c\' for details. 
\n" "

The hypothetical commands `show w\' and `show c\' should show the appropriate parts of the General Public License. Of course, your program\'s commands might be different; for a GUI interface, you would use an “about box”.

\n" "

You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.

\n" "

The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.

", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.License), QtGui.QApplication.translate( "Dialog", "License", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QtGui.QApplication.translate( "Dialog", "Docs", None, QtGui.QApplication.UnicodeUTF8)) if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) Dialog = QtGui.QDialog() ui = Ui_Dialog() ui.setupUi(Dialog) Dialog.show() sys.exit(app.exec_()) relational/relational_gui/__init__.py0000644000175100017510000000000012257142102017335 0ustar salvosalvorelational/relational_gui/maingui.py0000644000175100017510000006461712257142102017257 0ustar salvosalvo# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'relational_gui/maingui.ui' # # Created: Fri Dec 27 00:23:51 2013 # by: PyQt4 UI code generator 4.10.3 # # WARNING! All changes made in this file will be lost! from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s try: _encoding = QtGui.QApplication.UnicodeUTF8 def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(800, 612) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.verticalLayout_7 = QtGui.QVBoxLayout(self.centralwidget) self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) self.splitter_4 = QtGui.QSplitter(self.centralwidget) self.splitter_4.setOrientation(QtCore.Qt.Horizontal) self.splitter_4.setObjectName(_fromUtf8("splitter_4")) self.layoutWidget = QtGui.QWidget(self.splitter_4) self.layoutWidget.setObjectName(_fromUtf8("layoutWidget")) self.verticalLayout_11 = QtGui.QVBoxLayout(self.layoutWidget) self.verticalLayout_11.setMargin(0) self.verticalLayout_11.setObjectName(_fromUtf8("verticalLayout_11")) self.groupBox_3 = QtGui.QGroupBox(self.layoutWidget) self.groupBox_3.setObjectName(_fromUtf8("groupBox_3")) self.verticalLayout_5 = QtGui.QVBoxLayout(self.groupBox_3) self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) self.cmdAbout = QtGui.QPushButton(self.groupBox_3) self.cmdAbout.setObjectName(_fromUtf8("cmdAbout")) self.verticalLayout_5.addWidget(self.cmdAbout) self.cmdSurvey = QtGui.QPushButton(self.groupBox_3) self.cmdSurvey.setObjectName(_fromUtf8("cmdSurvey")) self.verticalLayout_5.addWidget(self.cmdSurvey) self.verticalLayout_11.addWidget(self.groupBox_3) self.groupBox_4 = QtGui.QGroupBox(self.layoutWidget) self.groupBox_4.setObjectName(_fromUtf8("groupBox_4")) self.verticalLayout_10 = QtGui.QVBoxLayout(self.groupBox_4) self.verticalLayout_10.setObjectName(_fromUtf8("verticalLayout_10")) self.cmdProduct = QtGui.QPushButton(self.groupBox_4) self.cmdProduct.setObjectName(_fromUtf8("cmdProduct")) self.verticalLayout_10.addWidget(self.cmdProduct) self.cmdDifference = QtGui.QPushButton(self.groupBox_4) self.cmdDifference.setObjectName(_fromUtf8("cmdDifference")) self.verticalLayout_10.addWidget(self.cmdDifference) self.cmdUnion = QtGui.QPushButton(self.groupBox_4) self.cmdUnion.setObjectName(_fromUtf8("cmdUnion")) self.verticalLayout_10.addWidget(self.cmdUnion) self.cmdIntersection = QtGui.QPushButton(self.groupBox_4) self.cmdIntersection.setObjectName(_fromUtf8("cmdIntersection")) self.verticalLayout_10.addWidget(self.cmdIntersection) self.cmdDivision = QtGui.QPushButton(self.groupBox_4) self.cmdDivision.setObjectName(_fromUtf8("cmdDivision")) self.verticalLayout_10.addWidget(self.cmdDivision) self.cmdJoin = QtGui.QPushButton(self.groupBox_4) self.cmdJoin.setObjectName(_fromUtf8("cmdJoin")) self.verticalLayout_10.addWidget(self.cmdJoin) self.cmdOuterLeft = QtGui.QPushButton(self.groupBox_4) self.cmdOuterLeft.setObjectName(_fromUtf8("cmdOuterLeft")) self.verticalLayout_10.addWidget(self.cmdOuterLeft) self.cmdOuterRight = QtGui.QPushButton(self.groupBox_4) self.cmdOuterRight.setObjectName(_fromUtf8("cmdOuterRight")) self.verticalLayout_10.addWidget(self.cmdOuterRight) self.cmdOuter = QtGui.QPushButton(self.groupBox_4) self.cmdOuter.setObjectName(_fromUtf8("cmdOuter")) self.verticalLayout_10.addWidget(self.cmdOuter) self.cmdProjection = QtGui.QPushButton(self.groupBox_4) self.cmdProjection.setObjectName(_fromUtf8("cmdProjection")) self.verticalLayout_10.addWidget(self.cmdProjection) self.cmdSelection = QtGui.QPushButton(self.groupBox_4) self.cmdSelection.setObjectName(_fromUtf8("cmdSelection")) self.verticalLayout_10.addWidget(self.cmdSelection) self.cmdRename = QtGui.QPushButton(self.groupBox_4) self.cmdRename.setObjectName(_fromUtf8("cmdRename")) self.verticalLayout_10.addWidget(self.cmdRename) self.cmdArrow = QtGui.QPushButton(self.groupBox_4) self.cmdArrow.setObjectName(_fromUtf8("cmdArrow")) self.verticalLayout_10.addWidget(self.cmdArrow) spacerItem = QtGui.QSpacerItem(20, 25, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout_10.addItem(spacerItem) self.verticalLayout_11.addWidget(self.groupBox_4) self.splitter_3 = QtGui.QSplitter(self.splitter_4) self.splitter_3.setOrientation(QtCore.Qt.Horizontal) self.splitter_3.setObjectName(_fromUtf8("splitter_3")) self.splitter_2 = QtGui.QSplitter(self.splitter_3) self.splitter_2.setOrientation(QtCore.Qt.Vertical) self.splitter_2.setObjectName(_fromUtf8("splitter_2")) self.table = QtGui.QTreeWidget(self.splitter_2) self.table.setMinimumSize(QtCore.QSize(450, 400)) self.table.setSizeIncrement(QtCore.QSize(0, 0)) self.table.setRootIsDecorated(False) self.table.setObjectName(_fromUtf8("table")) self.table.headerItem().setText(0, _fromUtf8("Empty relation")) self.layoutWidget1 = QtGui.QWidget(self.splitter_2) self.layoutWidget1.setObjectName(_fromUtf8("layoutWidget1")) self.verticalLayout_6 = QtGui.QVBoxLayout(self.layoutWidget1) self.verticalLayout_6.setSizeConstraint(QtGui.QLayout.SetMinimumSize) self.verticalLayout_6.setMargin(0) self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6")) self.lstHistory = QtGui.QListWidget(self.layoutWidget1) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lstHistory.sizePolicy().hasHeightForWidth()) self.lstHistory.setSizePolicy(sizePolicy) self.lstHistory.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.lstHistory.setBaseSize(QtCore.QSize(0, 0)) font = QtGui.QFont() font.setStrikeOut(False) self.lstHistory.setFont(font) self.lstHistory.setObjectName(_fromUtf8("lstHistory")) self.verticalLayout_6.addWidget(self.lstHistory) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) self.cmdOptimize = QtGui.QPushButton(self.layoutWidget1) self.cmdOptimize.setObjectName(_fromUtf8("cmdOptimize")) self.horizontalLayout_3.addWidget(self.cmdOptimize) self.cmdUndoOptimize = QtGui.QPushButton(self.layoutWidget1) self.cmdUndoOptimize.setObjectName(_fromUtf8("cmdUndoOptimize")) self.horizontalLayout_3.addWidget(self.cmdUndoOptimize) self.cmdClearHistory = QtGui.QPushButton(self.layoutWidget1) self.cmdClearHistory.setObjectName(_fromUtf8("cmdClearHistory")) self.horizontalLayout_3.addWidget(self.cmdClearHistory) self.verticalLayout_6.addLayout(self.horizontalLayout_3) self.splitter = QtGui.QSplitter(self.splitter_3) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setObjectName(_fromUtf8("splitter")) self.groupBox = QtGui.QGroupBox(self.splitter) self.groupBox.setMinimumSize(QtCore.QSize(0, 0)) self.groupBox.setMaximumSize(QtCore.QSize(300, 16777215)) self.groupBox.setObjectName(_fromUtf8("groupBox")) self.verticalLayout = QtGui.QVBoxLayout(self.groupBox) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.lstRelations = QtGui.QListWidget(self.groupBox) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lstRelations.sizePolicy().hasHeightForWidth()) self.lstRelations.setSizePolicy(sizePolicy) self.lstRelations.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.lstRelations.setObjectName(_fromUtf8("lstRelations")) self.verticalLayout.addWidget(self.lstRelations) self.cmdNew = QtGui.QPushButton(self.groupBox) self.cmdNew.setObjectName(_fromUtf8("cmdNew")) self.verticalLayout.addWidget(self.cmdNew) self.cmdLoad = QtGui.QPushButton(self.groupBox) self.cmdLoad.setObjectName(_fromUtf8("cmdLoad")) self.verticalLayout.addWidget(self.cmdLoad) self.cmdSave = QtGui.QPushButton(self.groupBox) self.cmdSave.setObjectName(_fromUtf8("cmdSave")) self.verticalLayout.addWidget(self.cmdSave) self.cmdEdit = QtGui.QPushButton(self.groupBox) self.cmdEdit.setObjectName(_fromUtf8("cmdEdit")) self.verticalLayout.addWidget(self.cmdEdit) self.cmdUnload = QtGui.QPushButton(self.groupBox) self.cmdUnload.setObjectName(_fromUtf8("cmdUnload")) self.verticalLayout.addWidget(self.cmdUnload) self.groupBox_2 = QtGui.QGroupBox(self.splitter) self.groupBox_2.setMinimumSize(QtCore.QSize(0, 0)) self.groupBox_2.setMaximumSize(QtCore.QSize(300, 16777215)) self.groupBox_2.setObjectName(_fromUtf8("groupBox_2")) self.verticalLayout_3 = QtGui.QVBoxLayout(self.groupBox_2) self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) self.lstAttributes = QtGui.QListWidget(self.groupBox_2) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lstAttributes.sizePolicy().hasHeightForWidth()) self.lstAttributes.setSizePolicy(sizePolicy) self.lstAttributes.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.lstAttributes.setObjectName(_fromUtf8("lstAttributes")) self.verticalLayout_3.addWidget(self.lstAttributes) self.verticalLayout_7.addWidget(self.splitter_4) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.txtResult = QtGui.QLineEdit(self.centralwidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.txtResult.sizePolicy().hasHeightForWidth()) self.txtResult.setSizePolicy(sizePolicy) self.txtResult.setObjectName(_fromUtf8("txtResult")) self.horizontalLayout_2.addWidget(self.txtResult) self.label = QtGui.QLabel(self.centralwidget) self.label.setObjectName(_fromUtf8("label")) self.horizontalLayout_2.addWidget(self.label) self.txtQuery = QtGui.QLineEdit(self.centralwidget) self.txtQuery.setObjectName(_fromUtf8("txtQuery")) self.horizontalLayout_2.addWidget(self.txtQuery) self.cmdClearQuery = QtGui.QPushButton(self.centralwidget) self.cmdClearQuery.setObjectName(_fromUtf8("cmdClearQuery")) self.horizontalLayout_2.addWidget(self.cmdClearQuery) self.cmdExecute = QtGui.QPushButton(self.centralwidget) self.cmdExecute.setObjectName(_fromUtf8("cmdExecute")) self.horizontalLayout_2.addWidget(self.cmdExecute) self.verticalLayout_7.addLayout(self.horizontalLayout_2) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 19)) self.menubar.setObjectName(_fromUtf8("menubar")) self.menuFile = QtGui.QMenu(self.menubar) self.menuFile.setObjectName(_fromUtf8("menuFile")) self.menuAbout = QtGui.QMenu(self.menubar) self.menuAbout.setObjectName(_fromUtf8("menuAbout")) self.action = QtGui.QAction(MainWindow) self.action.setObjectName(_fromUtf8("action")) self.menuRelations = QtGui.QMenu(self.menubar) self.menuRelations.setObjectName(_fromUtf8("menuRelations")) MainWindow.setMenuBar(self.menubar) self.actionAbout = QtGui.QAction(MainWindow) self.actionAbout.setMenuRole(QtGui.QAction.AboutRole) self.actionAbout.setObjectName(_fromUtf8("actionAbout")) self.action_Load_relation = QtGui.QAction(MainWindow) self.action_Load_relation.setObjectName(_fromUtf8("action_Load_relation")) self.action_Save_relation = QtGui.QAction(MainWindow) self.action_Save_relation.setObjectName(_fromUtf8("action_Save_relation")) self.action_Quit = QtGui.QAction(MainWindow) self.action_Quit.setMenuRole(QtGui.QAction.QuitRole) self.action_Quit.setObjectName(_fromUtf8("action_Quit")) self.actionCheck_for_new_versions = QtGui.QAction(MainWindow) self.actionCheck_for_new_versions.setObjectName(_fromUtf8("actionCheck_for_new_versions")) self.actionNew_relation = QtGui.QAction(MainWindow) self.actionNew_relation.setObjectName(_fromUtf8("actionNew_relation")) self.actionEdit_relation = QtGui.QAction(MainWindow) self.actionEdit_relation.setObjectName(_fromUtf8("actionEdit_relation")) self.actionNew_session = QtGui.QAction(MainWindow) self.actionNew_session.setObjectName(_fromUtf8("actionNew_session")) self.actionSave_session_as = QtGui.QAction(MainWindow) self.actionSave_session_as.setObjectName(_fromUtf8("actionSave_session_as")) self.actionManage_sessions = QtGui.QAction(MainWindow) self.actionManage_sessions.setObjectName(_fromUtf8("actionManage_sessions")) self.actionUnload_relation = QtGui.QAction(MainWindow) self.actionUnload_relation.setObjectName(_fromUtf8("actionUnload_relation")) self.menuFile.addSeparator() self.menuFile.addAction(self.action_Quit) self.menuAbout.addAction(self.actionAbout) self.menuAbout.addAction(self.actionCheck_for_new_versions) self.menuRelations.addAction(self.actionNew_relation) self.menuRelations.addAction(self.action_Load_relation) self.menuRelations.addAction(self.action_Save_relation) self.menuRelations.addAction(self.actionEdit_relation) self.menuRelations.addAction(self.actionUnload_relation) self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuRelations.menuAction()) self.menubar.addAction(self.menuAbout.menuAction()) self.label.setBuddy(self.txtQuery) self.retranslateUi(MainWindow) QtCore.QObject.connect(self.cmdClearQuery, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtQuery.clear) QtCore.QObject.connect(self.cmdClearHistory, QtCore.SIGNAL(_fromUtf8("clicked()")), self.lstHistory.clear) QtCore.QObject.connect(self.txtQuery, QtCore.SIGNAL(_fromUtf8("returnPressed()")), MainWindow.execute) QtCore.QObject.connect(self.cmdExecute, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.execute) QtCore.QObject.connect(self.cmdAbout, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.showAbout) QtCore.QObject.connect(self.cmdSurvey, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.showSurvey) QtCore.QObject.connect(self.cmdProduct, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addProduct) QtCore.QObject.connect(self.cmdDifference, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addDifference) QtCore.QObject.connect(self.cmdArrow, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addArrow) QtCore.QObject.connect(self.cmdRename, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addRename) QtCore.QObject.connect(self.cmdSelection, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addSelection) QtCore.QObject.connect(self.cmdProjection, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addProjection) QtCore.QObject.connect(self.cmdUnload, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.unloadRelation) QtCore.QObject.connect(self.cmdSave, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.saveRelation) QtCore.QObject.connect(self.cmdLoad, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.loadRelation) QtCore.QObject.connect(self.cmdOptimize, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.optimize) QtCore.QObject.connect(self.cmdUndoOptimize, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.undoOptimize) QtCore.QObject.connect(self.txtResult, QtCore.SIGNAL(_fromUtf8("returnPressed()")), self.txtQuery.setFocus) QtCore.QObject.connect(self.cmdOuterRight, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addORight) QtCore.QObject.connect(self.cmdOuter, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addOuter) QtCore.QObject.connect(self.cmdOuterLeft, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addOLeft) QtCore.QObject.connect(self.cmdJoin, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addJoin) QtCore.QObject.connect(self.cmdDivision, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addDivision) QtCore.QObject.connect(self.cmdIntersection, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addIntersection) QtCore.QObject.connect(self.cmdUnion, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.addUnion) QtCore.QObject.connect(self.lstRelations, QtCore.SIGNAL(_fromUtf8("itemDoubleClicked(QListWidgetItem*)")), MainWindow.printRelation) QtCore.QObject.connect(self.lstRelations, QtCore.SIGNAL(_fromUtf8("itemClicked(QListWidgetItem*)")), MainWindow.showAttributes) QtCore.QObject.connect(self.cmdClearQuery, QtCore.SIGNAL(_fromUtf8("clicked()")), self.txtQuery.setFocus) QtCore.QObject.connect(self.lstHistory, QtCore.SIGNAL(_fromUtf8("itemDoubleClicked(QListWidgetItem*)")), MainWindow.resumeHistory) QtCore.QObject.connect(self.actionAbout, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.showAbout) QtCore.QObject.connect(self.action_Load_relation, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.loadRelation) QtCore.QObject.connect(self.action_Save_relation, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.saveRelation) QtCore.QObject.connect(self.action_Quit, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.close) QtCore.QObject.connect(self.actionCheck_for_new_versions, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.checkVersion) QtCore.QObject.connect(self.cmdEdit, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.editRelation) QtCore.QObject.connect(self.actionEdit_relation, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.editRelation) QtCore.QObject.connect(self.cmdNew, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.newRelation) QtCore.QObject.connect(self.actionNew_relation, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.newRelation) QtCore.QObject.connect(self.actionUnload_relation, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.unloadRelation) QtCore.QMetaObject.connectSlotsByName(MainWindow) MainWindow.setTabOrder(self.cmdAbout, self.cmdSurvey) MainWindow.setTabOrder(self.cmdSurvey, self.cmdProduct) MainWindow.setTabOrder(self.cmdProduct, self.cmdDifference) MainWindow.setTabOrder(self.cmdDifference, self.cmdUnion) MainWindow.setTabOrder(self.cmdUnion, self.cmdIntersection) MainWindow.setTabOrder(self.cmdIntersection, self.cmdDivision) MainWindow.setTabOrder(self.cmdDivision, self.cmdJoin) MainWindow.setTabOrder(self.cmdJoin, self.cmdOuterLeft) MainWindow.setTabOrder(self.cmdOuterLeft, self.cmdOuterRight) MainWindow.setTabOrder(self.cmdOuterRight, self.cmdOuter) MainWindow.setTabOrder(self.cmdOuter, self.cmdProjection) MainWindow.setTabOrder(self.cmdProjection, self.cmdSelection) MainWindow.setTabOrder(self.cmdSelection, self.cmdRename) MainWindow.setTabOrder(self.cmdRename, self.cmdArrow) MainWindow.setTabOrder(self.cmdArrow, self.table) MainWindow.setTabOrder(self.table, self.lstHistory) MainWindow.setTabOrder(self.lstHistory, self.cmdOptimize) MainWindow.setTabOrder(self.cmdOptimize, self.cmdUndoOptimize) MainWindow.setTabOrder(self.cmdUndoOptimize, self.cmdClearHistory) MainWindow.setTabOrder(self.cmdClearHistory, self.lstRelations) MainWindow.setTabOrder(self.lstRelations, self.cmdLoad) MainWindow.setTabOrder(self.cmdLoad, self.cmdSave) MainWindow.setTabOrder(self.cmdSave, self.cmdUnload) MainWindow.setTabOrder(self.cmdUnload, self.lstAttributes) MainWindow.setTabOrder(self.lstAttributes, self.txtResult) MainWindow.setTabOrder(self.txtResult, self.txtQuery) MainWindow.setTabOrder(self.txtQuery, self.cmdClearQuery) MainWindow.setTabOrder(self.cmdClearQuery, self.cmdExecute) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "Relational", None)) self.groupBox_3.setTitle(_translate("MainWindow", "Menu", None)) self.cmdAbout.setText(_translate("MainWindow", "About", None)) self.cmdSurvey.setText(_translate("MainWindow", "Survey", None)) self.groupBox_4.setTitle(_translate("MainWindow", "Operators", None)) self.cmdProduct.setToolTip(_translate("MainWindow", "Product", None)) self.cmdProduct.setText(_translate("MainWindow", "*", None)) self.cmdDifference.setToolTip(_translate("MainWindow", "Difference", None)) self.cmdDifference.setText(_translate("MainWindow", "-", None)) self.cmdUnion.setToolTip(_translate("MainWindow", "Union", None)) self.cmdUnion.setText(_translate("MainWindow", "ᑌ", None)) self.cmdIntersection.setToolTip(_translate("MainWindow", "Intersection", None)) self.cmdIntersection.setText(_translate("MainWindow", "ᑎ", None)) self.cmdDivision.setToolTip(_translate("MainWindow", "Division", None)) self.cmdDivision.setText(_translate("MainWindow", "÷", None)) self.cmdJoin.setToolTip(_translate("MainWindow", "Natural join", None)) self.cmdJoin.setText(_translate("MainWindow", "ᐅᐊ", None)) self.cmdOuterLeft.setToolTip(_translate("MainWindow", "Left outer join", None)) self.cmdOuterLeft.setText(_translate("MainWindow", "ᐅLEFTᐊ", None)) self.cmdOuterRight.setToolTip(_translate("MainWindow", "Right outer join", None)) self.cmdOuterRight.setText(_translate("MainWindow", "ᐅRIGHTᐊ", None)) self.cmdOuter.setToolTip(_translate("MainWindow", "Full outer join", None)) self.cmdOuter.setText(_translate("MainWindow", "ᐅFULLᐊ", None)) self.cmdProjection.setToolTip(_translate("MainWindow", "Projection", None)) self.cmdProjection.setText(_translate("MainWindow", "π", None)) self.cmdSelection.setToolTip(_translate("MainWindow", "Selection", None)) self.cmdSelection.setText(_translate("MainWindow", "σ", None)) self.cmdRename.setToolTip(_translate("MainWindow", "Rename", None)) self.cmdRename.setText(_translate("MainWindow", "ρ", None)) self.cmdArrow.setText(_translate("MainWindow", "➡", None)) self.cmdOptimize.setText(_translate("MainWindow", "Optimize", None)) self.cmdUndoOptimize.setText(_translate("MainWindow", "Undo optimize", None)) self.cmdClearHistory.setText(_translate("MainWindow", "Clear history", None)) self.groupBox.setTitle(_translate("MainWindow", "Relations", None)) self.lstRelations.setSortingEnabled(True) self.cmdNew.setText(_translate("MainWindow", "New relation", None)) self.cmdLoad.setText(_translate("MainWindow", "Load relation", None)) self.cmdSave.setText(_translate("MainWindow", "Save relation", None)) self.cmdEdit.setText(_translate("MainWindow", "Edit relation", None)) self.cmdUnload.setText(_translate("MainWindow", "Unload relation", None)) self.groupBox_2.setTitle(_translate("MainWindow", "Attributes", None)) self.txtResult.setText(_translate("MainWindow", "_last1", None)) self.label.setText(_translate("MainWindow", "=", None)) self.cmdClearQuery.setText(_translate("MainWindow", "⌫", None)) self.cmdExecute.setText(_translate("MainWindow", "Execute", None)) self.menuFile.setTitle(_translate("MainWindow", "&File", None)) self.menuAbout.setTitle(_translate("MainWindow", "&Help", None)) self.menuRelations.setTitle(_translate("MainWindow", "Relations", None)) self.actionAbout.setText(_translate("MainWindow", "&About", None)) self.action_Load_relation.setText(_translate("MainWindow", "&Load relation", None)) self.action_Load_relation.setShortcut(_translate("MainWindow", "Ctrl+O", None)) self.action_Save_relation.setText(_translate("MainWindow", "&Save relation", None)) self.action_Save_relation.setShortcut(_translate("MainWindow", "Ctrl+S", None)) self.action_Quit.setText(_translate("MainWindow", "&Quit", None)) self.action_Quit.setShortcut(_translate("MainWindow", "Ctrl+Q", None)) self.actionCheck_for_new_versions.setText(_translate("MainWindow", "Check for new versions", None)) self.actionNew_relation.setText(_translate("MainWindow", "New relation", None)) self.actionNew_relation.setShortcut(_translate("MainWindow", "Ctrl+N", None)) self.actionEdit_relation.setText(_translate("MainWindow", "Edit relation", None)) self.actionEdit_relation.setShortcut(_translate("MainWindow", "Ctrl+E", None)) self.actionNew_session.setText(_translate("MainWindow", "New session", None)) self.actionSave_session_as.setText(_translate("MainWindow", "Save session as", None)) self.actionSave_session_as.setToolTip(_translate("MainWindow", "Save session as", None)) self.actionManage_sessions.setText(_translate("MainWindow", "Manage sessions", None)) self.actionUnload_relation.setText(_translate("MainWindow", "Unload relation", None)) relational/TODO0000644000175100017510000000000012257142102012716 0ustar salvosalvo