diff --git a/solution.pl b/solution.pl index 0bbdb07..9fe7ce2 100644 --- a/solution.pl +++ b/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 [+, +] for the column name + * we return [, ] 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 (+). 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. -denotes a prolog value that can be stored into a row. You do -not need to handle parsing Prolog (and ) by yourself, -we’ll show how to do it below. +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 WHERE */ 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 FROM
WHERE */ 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
*/ 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 FROM
*/ 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),