comments
This commit is contained in:
parent
1ce0b1db2f
commit
cac813cfc7
68
solution.pl
68
solution.pl
|
@ -2,6 +2,25 @@
|
||||||
* Authors:
|
* Authors:
|
||||||
* Dubois Brieuc
|
* Dubois Brieuc
|
||||||
* Dubois Simon
|
* 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.
|
:- dynamic tables/0.
|
||||||
|
@ -159,7 +178,9 @@ delete(_, _).
|
||||||
|
|
||||||
|
|
||||||
does_match([], _, _) :- !.
|
does_match([], _, _) :- !.
|
||||||
|
/**
|
||||||
|
* fails if conditons isn't respected in row
|
||||||
|
*/
|
||||||
does_match([Cond|Rest], Table, Row) :-
|
does_match([Cond|Rest], Table, Row) :-
|
||||||
% Extract the operator, field and value from the condition
|
% Extract the operator, field and value from the condition
|
||||||
Cond =.. [Operator | T],
|
Cond =.. [Operator | T],
|
||||||
|
@ -222,13 +243,17 @@ selec(Table, _, _, _) :-
|
||||||
!.
|
!.
|
||||||
|
|
||||||
selec(Table, Selector, Cond, Projection) :-
|
selec(Table, Selector, Cond, Projection) :-
|
||||||
|
%fetch columns names and all rows of Table
|
||||||
tabl(Table, Cols),
|
tabl(Table, Cols),
|
||||||
row(Table, R),
|
row(Table, R),
|
||||||
|
%remove rows that don't respect the conditions
|
||||||
does_match(Cond, Table, R),
|
does_match(Cond, Table, R),
|
||||||
|
%reduce result to only selected columns
|
||||||
selector(R,Cols, Selector, [],[],ColumnNames,ColumnValue),
|
selector(R,Cols, Selector, [],[],ColumnNames,ColumnValue),
|
||||||
|
%reorder result to match query order
|
||||||
reverse(ColumnNames, Names),
|
reverse(ColumnNames, Names),
|
||||||
reverse(ColumnValue, Values),
|
reverse(ColumnValue, Values),
|
||||||
|
%unify the lists to projection
|
||||||
Projection = Names/Values.
|
Projection = Names/Values.
|
||||||
|
|
||||||
selec(Table, *, Cond, Projection) :-
|
selec(Table, *, Cond, Projection) :-
|
||||||
|
@ -238,17 +263,18 @@ selec(Table, *, Cond, Projection) :-
|
||||||
Projection = Cols/R.
|
Projection = Cols/R.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Row: A row from the table
|
* +Row: A row from the table
|
||||||
* Cols: name of the column of the table
|
* +Cols: name of the column of the table
|
||||||
* [Selector|Selectors] name(s) of the column(s) for selection
|
* +[Selector|Selectors] name(s) of the column(s) for selection
|
||||||
* AccCols: acumulator list for the column(s) name(s)
|
* +AccCols: acumulator list for the column(s) name(s)
|
||||||
* AccVals: acumulator list for the row(s) values
|
* +AccVals: acumulator list for the row(s) values
|
||||||
* ColumnNames: List returning the column(s) name(s)
|
* -ColumnNames: List returning the column(s) name(s)
|
||||||
* ColumnValue: List returning the row values for each column
|
* -ColumnValue: List returning the row values for each column
|
||||||
*
|
*
|
||||||
* This predicate return
|
* This predicate return
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
%base case
|
||||||
selector(_,_,[],ColumnNames, ColumnValue, ColumnNames, ColumnValue):-!.
|
selector(_,_,[],ColumnNames, ColumnValue, ColumnNames, ColumnValue):-!.
|
||||||
|
|
||||||
selector(Row, Cols, [+Selector|Selectors], AccCols, AccVals, 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
|
%find the value corresponding to the column in the row
|
||||||
nth0(Index, Cols, Selector),
|
nth0(Index, Cols, Selector),
|
||||||
nth0(Index, Row, Value),
|
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)
|
selector(Row, Cols, Selectors, [Selector|AccCols], [Value|AccVals], ColumnNames, ColumnValue)
|
||||||
;
|
;
|
||||||
string_concat(Selector, " isn't a column of table ", Error),
|
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
|
lined before (+<atom>). <cond>denotes a Prolog goal, in Prolog syntax
|
||||||
— following the same format as the possible values of items of the Conds
|
— following the same format as the possible values of items of the Conds
|
||||||
list passed to selec and delete.
|
list passed to selec and delete.
|
||||||
<value>denotes a prolog value that can be stored into a row. You do
|
<value>denotes a prolog value that can be stored into a row.
|
||||||
not need to handle parsing Prolog (<cond>and <value>) by yourself,
|
|
||||||
we’ll show how to do it below.
|
|
||||||
The semantics of this predicate is that of the SQL-predicate contained in
|
The semantics of this predicate is that of the SQL-predicate contained in
|
||||||
the Query string.
|
the Query string.
|
||||||
A “SELECT” query maps to the selec predicate, while an “INSERT”
|
A “SELECT” query maps to the selec predicate, while an “INSERT”
|
||||||
|
@ -333,24 +357,32 @@ query(Query, Result):-
|
||||||
apply(Fun, Args),
|
apply(Fun, Args),
|
||||||
last(Args, Result).
|
last(Args, Result).
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For all parse_query on Query must be initiated
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse SELECT * FROM <table> WHERE <conds>
|
* Parse SELECT * FROM <table> WHERE <conds>
|
||||||
*/
|
*/
|
||||||
parse_query(Query, selec, [AtomTable, *, AtomsConds, R]):-
|
parse_query(Query, selec, [AtomTable, *, AtomsConds, R]):-
|
||||||
|
%split the query
|
||||||
split_string(Query, " ", ",;+", SplitQuery),
|
split_string(Query, " ", ",;+", SplitQuery),
|
||||||
append(["SELECT"], L1, SplitQuery),
|
append(["SELECT"], L1, SplitQuery),
|
||||||
append(["*"], ["FROM"|L2], L1),
|
append(["*"], ["FROM"|L2], L1),
|
||||||
append([Table], ["WHERE"|Conds],L2),
|
append([Table], ["WHERE"|Conds],L2),
|
||||||
|
%cast into correct type
|
||||||
atom_string(AtomTable, Table),
|
atom_string(AtomTable, Table),
|
||||||
maplist(parse_cond, AtomsConds, Conds),!.
|
maplist(parse_cond, AtomsConds, Conds),!.
|
||||||
/**
|
/**
|
||||||
* Parse SELECT <cols> FROM <table> WHERE <conds>
|
* Parse SELECT <cols> FROM <table> WHERE <conds>
|
||||||
*/
|
*/
|
||||||
parse_query(Query, selec, [AtomTable, AtomsSelectors, AtomsConds, R]):-
|
parse_query(Query, selec, [AtomTable, AtomsSelectors, AtomsConds, R]):-
|
||||||
|
%split the query
|
||||||
split_string(Query, " ", ",;+", SplitQuery),
|
split_string(Query, " ", ",;+", SplitQuery),
|
||||||
append(["SELECT"], L1, SplitQuery),
|
append(["SELECT"], L1, SplitQuery),
|
||||||
append(Selectors, ["FROM"|L2], L1),
|
append(Selectors, ["FROM"|L2], L1),
|
||||||
append([Table], ["WHERE"|Conds],L2),
|
append([Table], ["WHERE"|Conds],L2),
|
||||||
|
%cast into correct type
|
||||||
atom_string(AtomTable, Table),
|
atom_string(AtomTable, Table),
|
||||||
maplist(atom_string, AtomsSelectors1, Selectors),
|
maplist(atom_string, AtomsSelectors1, Selectors),
|
||||||
maplist(add_plus, AtomsSelectors, AtomsSelectors1),
|
maplist(add_plus, AtomsSelectors, AtomsSelectors1),
|
||||||
|
@ -360,9 +392,11 @@ parse_query(Query, selec, [AtomTable, AtomsSelectors, AtomsConds, R]):-
|
||||||
* Parse SELECT * FROM <table>
|
* Parse SELECT * FROM <table>
|
||||||
*/
|
*/
|
||||||
parse_query(Query, selec, [AtomTable, *, R]):-
|
parse_query(Query, selec, [AtomTable, *, R]):-
|
||||||
|
%split the query
|
||||||
split_string(Query, " ", ",;+", SplitQuery),
|
split_string(Query, " ", ",;+", SplitQuery),
|
||||||
append(["SELECT"], L1, SplitQuery),
|
append(["SELECT"], L1, SplitQuery),
|
||||||
append(["*"], ["FROM",Table], L1),
|
append(["*"], ["FROM",Table], L1),
|
||||||
|
%cast into correct type
|
||||||
atom_string(AtomTable, Table),
|
atom_string(AtomTable, Table),
|
||||||
maplist(parse_cond, AtomsConds, Conds),!.
|
maplist(parse_cond, AtomsConds, Conds),!.
|
||||||
|
|
||||||
|
@ -370,23 +404,31 @@ parse_query(Query, selec, [AtomTable, *, R]):-
|
||||||
* Parse SELECT <cols> FROM <table>
|
* Parse SELECT <cols> FROM <table>
|
||||||
*/
|
*/
|
||||||
parse_query(Query, selec, [AtomTable, AtomsSelectors, R]):-
|
parse_query(Query, selec, [AtomTable, AtomsSelectors, R]):-
|
||||||
|
%split the query
|
||||||
split_string(Query, " ", ",;+", SplitQuery),
|
split_string(Query, " ", ",;+", SplitQuery),
|
||||||
append(["SELECT"], L1, SplitQuery),
|
append(["SELECT"], L1, SplitQuery),
|
||||||
append(Selectors, ["FROM",Table], L1),
|
append(Selectors, ["FROM",Table], L1),
|
||||||
|
%cast into correct type
|
||||||
atom_string(AtomTable, Table),
|
atom_string(AtomTable, Table),
|
||||||
maplist(atom_string, AtomsSelectors1, Selectors),
|
maplist(atom_string, AtomsSelectors1, Selectors),
|
||||||
maplist(add_plus, AtomsSelectors, AtomsSelectors1).
|
maplist(add_plus, AtomsSelectors, AtomsSelectors1).
|
||||||
|
|
||||||
parse_query(Query, insert, [AtomTable, Values]):-
|
parse_query(Query, insert, [AtomTable, Values]):-
|
||||||
|
%split the query
|
||||||
split_string(Query, " ", '",();', SplitQuery),
|
split_string(Query, " ", '",();', SplitQuery),
|
||||||
append(["INSERT", "INTO"], L1, SplitQuery),
|
append(["INSERT", "INTO"], L1, SplitQuery),
|
||||||
L1 = [Table | L2],
|
L1 = [Table | L2],
|
||||||
append(_, ["VALUES"|Values1], L2),
|
append(_, ["VALUES"|Values1], L2),
|
||||||
|
%cast into correct type
|
||||||
maplist(is_number, Values, Values1),
|
maplist(is_number, Values, Values1),
|
||||||
atom_string(AtomTable, Table).
|
atom_string(AtomTable, Table).
|
||||||
|
|
||||||
add_plus(+A, A).
|
add_plus(+A, A).
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For all parse_cond only Cond must be initiated
|
||||||
|
*/
|
||||||
|
|
||||||
% parse >= conditon
|
% parse >= conditon
|
||||||
parse_cond(+AtomLeft>=AtomRight, Cond):-
|
parse_cond(+AtomLeft>=AtomRight, Cond):-
|
||||||
string_chars(Cond, Code),
|
string_chars(Cond, Code),
|
||||||
|
|
Loading…
Reference in New Issue