This commit is contained in:
duboissim 2024-03-15 23:19:57 +01:00
parent 1ce0b1db2f
commit cac813cfc7
1 changed files with 55 additions and 13 deletions

View File

@ -2,6 +2,25 @@
* Authors:
* Dubois Brieuc
* Dubois Simon
*
* Known Limitation and problems:
* Currently a condtion in a query as to contain no space in order to function properly
* Ex: the condtion +name="Dakota" will work but the conditions +name = "Dakota"
* or +name="North Dakota" will not. This is due to the way we parse the query. We did it
* with split_string. We were not able to use the prolog_term predicate given to us.
*
* SQL test:
* Test 10 failed because instead of returning [+<atom>, +<atom>] for the column name
* we return [<atom>, <atom>] because that's how we store the column names after an insert
*
* Test 12 and 21:
* When we return row of an empty table instead of having [] we have [_] same thing happens after
* we drop a table.
*
* DCG test:
* Test 5 failed:
* We don't cover the case where the number of values inserted isn't the same as the number of columns
* in the table.
*/
:- dynamic tables/0.
@ -159,7 +178,9 @@ delete(_, _).
does_match([], _, _) :- !.
/**
* fails if conditons isn't respected in row
*/
does_match([Cond|Rest], Table, Row) :-
% Extract the operator, field and value from the condition
Cond =.. [Operator | T],
@ -222,13 +243,17 @@ selec(Table, _, _, _) :-
!.
selec(Table, Selector, Cond, Projection) :-
%fetch columns names and all rows of Table
tabl(Table, Cols),
row(Table, R),
%remove rows that don't respect the conditions
does_match(Cond, Table, R),
%reduce result to only selected columns
selector(R,Cols, Selector, [],[],ColumnNames,ColumnValue),
%reorder result to match query order
reverse(ColumnNames, Names),
reverse(ColumnValue, Values),
%unify the lists to projection
Projection = Names/Values.
selec(Table, *, Cond, Projection) :-
@ -238,17 +263,18 @@ selec(Table, *, Cond, Projection) :-
Projection = Cols/R.
/**
* Row: A row from the table
* Cols: name of the column of the table
* [Selector|Selectors] name(s) of the column(s) for selection
* AccCols: acumulator list for the column(s) name(s)
* AccVals: acumulator list for the row(s) values
* ColumnNames: List returning the column(s) name(s)
* ColumnValue: List returning the row values for each column
* +Row: A row from the table
* +Cols: name of the column of the table
* +[Selector|Selectors] name(s) of the column(s) for selection
* +AccCols: acumulator list for the column(s) name(s)
* +AccVals: acumulator list for the row(s) values
* -ColumnNames: List returning the column(s) name(s)
* -ColumnValue: List returning the row values for each column
*
* This predicate return
*/
%base case
selector(_,_,[],ColumnNames, ColumnValue, ColumnNames, ColumnValue):-!.
selector(Row, Cols, [+Selector|Selectors], AccCols, AccVals, ColumnNames, ColumnValue):-
@ -256,7 +282,7 @@ selector(Row, Cols, [+Selector|Selectors], AccCols, AccVals, ColumnNames, Column
%find the value corresponding to the column in the row
nth0(Index, Cols, Selector),
nth0(Index, Row, Value),
%go to next column tho evaluate
%go to next column tho evaluate and store value and corresponging name
selector(Row, Cols, Selectors, [Selector|AccCols], [Value|AccVals], ColumnNames, ColumnValue)
;
string_concat(Selector, " isn't a column of table ", Error),
@ -299,9 +325,7 @@ ble names are atoms, while column names should follow the format out-
lined before (+<atom>). <cond>denotes a Prolog goal, in Prolog syntax
following the same format as the possible values of items of the Conds
list passed to selec and delete.
<value>denotes a prolog value that can be stored into a row. You do
not need to handle parsing Prolog (<cond>and <value>) by yourself,
well show how to do it below.
<value>denotes a prolog value that can be stored into a row.
The semantics of this predicate is that of the SQL-predicate contained in
the Query string.
A SELECT query maps to the selec predicate, while an INSERT
@ -333,24 +357,32 @@ query(Query, Result):-
apply(Fun, Args),
last(Args, Result).
/**
* For all parse_query on Query must be initiated
*/
/**
* Parse SELECT * FROM <table> WHERE <conds>
*/
parse_query(Query, selec, [AtomTable, *, AtomsConds, R]):-
%split the query
split_string(Query, " ", ",;+", SplitQuery),
append(["SELECT"], L1, SplitQuery),
append(["*"], ["FROM"|L2], L1),
append([Table], ["WHERE"|Conds],L2),
%cast into correct type
atom_string(AtomTable, Table),
maplist(parse_cond, AtomsConds, Conds),!.
/**
* Parse SELECT <cols> FROM <table> WHERE <conds>
*/
parse_query(Query, selec, [AtomTable, AtomsSelectors, AtomsConds, R]):-
%split the query
split_string(Query, " ", ",;+", SplitQuery),
append(["SELECT"], L1, SplitQuery),
append(Selectors, ["FROM"|L2], L1),
append([Table], ["WHERE"|Conds],L2),
%cast into correct type
atom_string(AtomTable, Table),
maplist(atom_string, AtomsSelectors1, Selectors),
maplist(add_plus, AtomsSelectors, AtomsSelectors1),
@ -360,9 +392,11 @@ parse_query(Query, selec, [AtomTable, AtomsSelectors, AtomsConds, R]):-
* Parse SELECT * FROM <table>
*/
parse_query(Query, selec, [AtomTable, *, R]):-
%split the query
split_string(Query, " ", ",;+", SplitQuery),
append(["SELECT"], L1, SplitQuery),
append(["*"], ["FROM",Table], L1),
%cast into correct type
atom_string(AtomTable, Table),
maplist(parse_cond, AtomsConds, Conds),!.
@ -370,23 +404,31 @@ parse_query(Query, selec, [AtomTable, *, R]):-
* Parse SELECT <cols> FROM <table>
*/
parse_query(Query, selec, [AtomTable, AtomsSelectors, R]):-
%split the query
split_string(Query, " ", ",;+", SplitQuery),
append(["SELECT"], L1, SplitQuery),
append(Selectors, ["FROM",Table], L1),
%cast into correct type
atom_string(AtomTable, Table),
maplist(atom_string, AtomsSelectors1, Selectors),
maplist(add_plus, AtomsSelectors, AtomsSelectors1).
parse_query(Query, insert, [AtomTable, Values]):-
%split the query
split_string(Query, " ", '",();', SplitQuery),
append(["INSERT", "INTO"], L1, SplitQuery),
L1 = [Table | L2],
append(_, ["VALUES"|Values1], L2),
%cast into correct type
maplist(is_number, Values, Values1),
atom_string(AtomTable, Table).
add_plus(+A, A).
/**
* For all parse_cond only Cond must be initiated
*/
% parse >= conditon
parse_cond(+AtomLeft>=AtomRight, Cond):-
string_chars(Cond, Code),