comments
This commit is contained in:
parent
1ce0b1db2f
commit
cac813cfc7
68
solution.pl
68
solution.pl
|
@ -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,
|
||||
we’ll 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),
|
||||
|
|
Loading…
Reference in New Issue