UT: replace with incorrect db key

UT: replace with incorrect db key

:- begin_tests(vd, [setup(setup)]).

:- multifile prolog:message//1.

:- use_module(u(v)).
:- use_module(u(vd)).
:- use_module(u(internal/db_i)).
:- use_module(u(internal/objects_i)).
:- use_module(u(util/lambda)).
:- use_module(library(aggregate)).
:- use_module(library(ordsets)).

test(clear_test_db, [fail, setup(db_clear(people))]) :-

	db_recorded(people, _).

test(db_clear, [setup(model_db), List == []]) :-

   reload_classes,

   % clear all DBs with citizen_v
   (  db_name(DB_Key),
      (  named_args_unify(DB_Key, citizen_v, [], [], _)
      -> db_clear(DB_Key)
      ;  true
      ),
      fail ; true
   ),

   findall(X,
           (db_i:current_predicate(citizen_v, X), call(db_i:X)),
           List).

test(db_copy, [setup(model_db), N =:= 3]) :-

   db_copy(people, people2),
   findall('.', db_recorded(people2, _), L),
   length(L, N).

test(db_erase1, [setup(model_db)]) :-
   (  named_args_unify(people, _,
                       [weight, surname], [73, _], X),
      db_erase(X),
      fail ; true
   ),
   findall(Y,
           db_recorded(people, Y),
           LY),
   assertion(LY = [man_v(_, _, _, _, _, 'Eva', woman, _, _)]).

test(db_erase2, [setup(db_clear(people))]) :-
   db_construct(people, citizen_v,
                [birthday, sex],
                [1994, man], C1),
   db_size(people, S1),
   assertion(S1 == 1),
   obj_downcast(C1, C2),
   functor(C2, CC, _),
   assertion(CC == callup_v),
   db_erase(C2),
   db_size(people, S2),
   assertion(S2 == 0).

test(db_iterate1, [setup(model_db), N =:= 3]) :-

   findall('.', db_iterate(people, true, _), L),
   length(L, N).

test(db_iterate2, [setup(model_db), N =:= 2]) :-

   findall(O, db_iterate(people, sex(man), O), L),
   length(L, N).

test(db_iterate3, [setup(model_db), fail]) :-

   db_iterate(people, unexisting_name(man_v), _).

test(db_iterate4, [setup(model_db), N =:= 2]) :-

   findall(O, db_iterate(people, functor(man_v), O), L),
   length(L, N).

test(db_iterate5, [setup(model_db), N =:= 3]) :-

   findall(O, db_iterate(people, functor(_), O), L),
   length(L, N).

test(db_iterate6, [setup(model_db), N =:= 3]) :-

   findall(O, db_iterate(people, same_or_descendant(man_v), O), L),
   length(L, N).

test(db_iterate7, [setup(model_db), N =:= 1]) :-

   findall(O, db_iterate(people, same_or_descendant(citizen_v), O), L),
   length(L, N).

test(db_iterate8, [setup(model_db)]) :-

   findall(Surname, db_iterate(people, surname(Surname), _), SL),
   assertion(SL =@= [_, _, 'Mayakovsky']),
   findall(Surname, db_iterate(people, sex(Surname), _), SL2),
   assertion(SL2 == [man, woman, man]).

test(db_iterate9, [setup(model_db), N == 1]) :-

   aggregate_all(count, db_iterate(people, surname(+bound), _), N).

test(db_iterate10, [setup(model_db), N == 2]) :-

   aggregate_all(count, db_iterate(people, surname(+free), _), N).

test(db_iterate11, [setup(model_db)]) :-

   aggregate_all(count,
                 db_iterate(people,
                            surname('Mayakovsky') /\ surname(+free), _),
                 N1),
   assertion(N1 == 0),
   aggregate_all(count,
                 db_iterate(people,
                            surname(+free) /\ surname('Mayakovsky'), _),
                 N2),
   assertion(N2 == 0),
   aggregate_all(count,
                 db_iterate(people,
                            surname(+free) /\ surname(+bound), _),
                 N3),
   assertion(N3 == 0),
   aggregate_all(count,
                 db_iterate(people,
                            surname(+free) \/ surname(+bound), _),
                 N4),
   assertion(N4 == 3),
   aggregate_all(count,
                 db_iterate(people,
                            surname('Mayakovsky') /\ surname(+bound), _),
                 N5),
   assertion(N5 == 1),
   aggregate_all(count,
                 db_iterate(people,
                            surname(+bound) /\ surname('Mayakovsky'), _),
                 N6),
   assertion(N6 == 1).

test(db_to_list, [setup(model_db)]) :-

   db_to_list(people, man_v, L1),
   length(L1, N1),
   assertion(N1 =:= 2),

   db_to_list(people, citizen_v, L2),
   length(L2, N2),
   assertion(N2 =:= 1),

   db_to_list(people, _, L3),
   length(L3, N3),
   assertion(N3 =:= 3).

test(db_put_object1,
     [setup(model_db),
      List == [['Adam'], ['Eva'], ['Moses'], ['Vladimir']]
      ]) :-

   obj_construct(man_v, [name], ['Moses'], Man),
   db_put_object(people, Man),
   db_select_list(people, _, [name], List).

test(db_put_object2, [setup(model_db)]) :-

   obj_construct(man_v, [name], ['Moses'], Man0),
   obj_rebase((object_v -> db_object_v), Man0, Man),
   db_put_object(people, Man).

test(db_put_object3,
     [setup(model_db),
      error(db_obj_replace_protector(people2, _, Man))]) :-

   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man), !,
   db_put_object(people2, Man).

test(db_put_object4, [setup(model_db)]) :-
% replacing

   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_rewrite(Man0, [name], ['Moses'], [_], Man1),
   db_put_object(people2, throw, Man1, Man2, Replaced),
   named_args_unify(Man2,
                    [name, db_key, db_ref],
                    [New_Name, DB_Key, DB_Ref]),
   assertion(New_Name =@= _),
   assertion(Replaced == replaced),
   assertion(nonvar(DB_Ref)),
   assertion(DB_Key == people2),

   db_size(people2, N),
   assertion(N =:= 1).

% replacing rebased
test(db_put_object4_1, [setup(model_db), error(class_parents_mismatch(_,_,_,_))]) :-
   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_rewrite(Man0, [name], ['Moses'], [_], Man1),
   obj_parents(Man1, [man_v, tarjan_vertex_v, db_object_v, object_v, object_base_v], Man2),
   db_put_object(people2, throw, Man2, _, _).

% replacing downcasted
test(db_put_object4_2, [setup(db_clear(people2))]) :-
   db_construct(people2, citizen_v,
                [birthday, sex, name, surname, id],
                [1994, man, l, k, 199442]),
   db_recorded(people2, Man1), !,
   obj_downcast(Man1, callup_v, Man2),
   db_put_object(people2, throw, Man2, Man3, Replaced),
   named_args_unify(Man3,
                    [name, db_key, db_ref],
                    [New_Name, DB_Key, DB_Ref]),
   assertion(New_Name == l),
   assertion(Replaced == replaced),
   assertion(nonvar(DB_Ref)),
   assertion(DB_Key == people2),
   db_size(people2, N),
   assertion(N =:= 1).

% replace with incorrect db_key
test(db_put_object4_3,
     [setup((db_clear(people), db_clear(people2))),
      error(_)]) :-
   db_construct(people, man_v, [name, surname], [1,2], M1),
   db_construct(people2, man_v, [name,surname], [1,2]),
   obj_rewrite(M1, [db_key, deb_ref], [_, _], [people2, _], MM1),
   db_put_object(people, throw, MM1, _, _).

test(db_put_object5,
     [setup(model_db),
      error(domain_error(unbound_db_ref, DB_Ref))]) :-

   db_construct(people, man_v, [name], ['Moses']),
   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_field(Man0, db_ref, DB_Ref),
   db_put_object(people, throw, Man0, _, _).

test(db_put_object6,
     [setup(model_db),
      error(domain_error(unbound_or_same_db_key, people2))]) :-

   db_construct(people, man_v, [name], ['Moses']),
   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_reset_fields([db_ref], Man0, Man),
   db_put_object(people, throw, Man, _, _).

test(db_put_object7,
     [setup(model_db),
      error(db_obj_replace_protector(people2, replaced, Man1))]) :-

   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_rewrite(Man0, [db_ref, name], [_, 'Moses'], [_, _], Man1),
   db_put_object(people2, throw, Man1, _, replaced).
   % does not replace because of unbound db_ref

test(db_put_object8,
     [setup(model_db),
      error(db_obj_replace_protector(people2, replaced, Man))]) :-

   db_construct(people2, man_v, [name], ['Moses']),
   obj_construct(man_v, [name], ['Simeon'], Man),
   db_put_object(people2, _, Man, _, replaced).
   % does not replace because of not db_object_v descendant

test(db_put_object9,
     [blocked(rebase_collision), setup(model_db),
      List == [['Adam'], ['Eva'], ['Moses'], ['Vladimir']]
      ]) :-

   obj_construct(man_v, [name], ['Moses'], Man0),
   obj_rebase((object_v -> db_object_v), Man0, Man1),
   obj_rebase((object_v -> tarjan_vertex_v), Man1, Man),
   db_put_object(people, Man),
   db_select_list(people, _, [name], List).

test(db_recorda1,
     [setup(model_db),
      List == [['Moses'], ['Adam'], ['Eva'], ['Vladimir']]
      ]) :-

   obj_construct(man_v, [name], ['Moses'], Man),
   db_recorda(people, Man),
   db_select_list(people, _, [name], List).

test(db_put_objects,
    [setup(db_clear(people)),
     DB_Size =:= 3]
    ) :-

	maplist(obj_construct(man_v, [name]),
		[['Valera'], ['Vika'], ['Yura']],
		Men),

	db_put_objects(people,
		       Men+\El^member(El, Men),
		       fail),

	db_size(people, DB_Size).

test(db_recorded_bug1, [setup(model_db), N =:= 3]) :-

   findall('.', db_recorded(people, _), L),
   length(L, N).

test(db_recorded1,
     [setup(model_db),
      error(domain_error(db_object_v_descendant, X))]) :-

   obj_construct(man_v, [sex], [man], X),
   db_recorded(people, X).

test(db_recorded2, [setup(model_db)]) :-

   findall('.',
           (obj_construct(man_v, [sex], [man], X0),
            obj_rebase((object_v -> db_object_v), X0, X),
            db_recorded(people, X)),
           L2),
   length(L2, N2),
   assertion(N2 =:= 1).

test(db_recorded3, [setup(model_db)]) :-

   findall('.',
           (obj_construct(man_v, [], [], X0),
            obj_rebase((object_v -> db_object_v), X0, X),
            db_recorded(people, X)),
           L2),
   length(L2, N2),
   assertion(N2 =:= 2).

test(db_recorded4, [setup(model_db)]) :-

   findall('.',
           (obj_construct(man_v, [height], [1.76], X0),
            obj_rebase((object_v -> db_object_v), X0, X),
            db_recorded(people, X)),
           L2),
   length(L2, N2),
   assertion(N2 =:= 2).

test(db_recorded5, [setup(db_clear(people))]) :-

   db_construct(people, man_v, [], []),
   db_recorded(people, X), !,
   db_recorded(people, X).

% test(db_rewrite1,
%      [setup(model_db),
%       List =@= [['Adam', 'Kasperski', 66],
%                 ['Eva', 'Kasperski', 66],
%                 ['Vladimir', 'Kasperski', 66]]
%      ]) :-

%    db_rewrite(people, _,
%               [weight, surname], _, [66, 'Kasperski']),
%    db_select_list(people, _, [name, surname, weight], List).

% test(db_rewrite2,
%      [setup(model_db),
%       List =@= [['Adam', 'Kasperski', 66],
%                 ['Eva', 'Kasperski', 66],
%                 ['Vladimir', 'Mayakovsky', _]]
%      ]) :-

%    db_rewrite(people, man_v,
%               [weight, surname], _, [66, 'Kasperski']),
%    db_select_list(people, _, [name, surname, weight], List).

test(db_search,
     [setup(model_db),
      List == [['Adam'], ['Vladimir']]
     ]) :-

   db_search(people, people2, db_search_pred),
   db_select_list(people2, _, [name], List).

db_search_pred(Man) :-

  obj_field(Man, sex, Sex),
  Sex == man.

test(db_select1,
     [setup(model_db),
      List =@= [[man_v, man, 'Adam', _, 73, _],
                [man_v, woman, 'Eva', _, 64, _],
                [citizen_v, man, 'Vladimir', 'Mayakovsky', _,
                 ['Soviet Union']]]
      ]) :-

   findall(Row,
           db_select(people,
                     [class, sex, name, surname, weight, country],
                     Row),
           List
          ).

test(db_select2,
     [setup(model_db),
      List =@= [[man_v, man, 'Adam', _, 73, _],
                [man_v, woman, 'Eva', _, 64, _]]
      ]) :-

   findall(Row,
           (   Row = [man_v|_],
               db_select(people,
                         [functor, sex, name, surname, weight,
                          country],
                         Row)
           ), List
          ).

test(db_select3,
     [setup((model_db,
      db_construct(people, citizen_v, [id, sex, name, age], [2, man, 'Igor', 19]))),
     Classes == [callup_v]]) :-
   findall(Class, db_select(people,  [name, class], ['Igor', Class]), Classes).

test(db_select_list1,
     [setup(model_db),
      List =@= [[man_v, man, 'Adam', _, 73, _],
                [man_v, woman, 'Eva', _, 64, _],
                [citizen_v, man, 'Vladimir', 'Mayakovsky', _,
                 ['Soviet Union']]]
      ]) :-

   db_select_list(people, _,
                  [class, sex, name, surname, weight, country],
                  List).

test(db_select_list2,
     [setup(model_db),
      List =@= [[man_v, man, 'Adam', _, 73, _],
                [man_v, woman, 'Eva', _, 64, _]]
      ]) :-

   db_select_list(people, man_v, _,
                  [class, sex, name, surname, weight, country],
                  List).

test(db_select_list3,
     [setup(model_db),
      error(no_object_field(_, country))
      ]) :-

   db_select_list(people, man_v, throw,
                  [class, sex, name, surname, weight, country],
                  _).

test(filter_on_db,
     [setup(model_db),
      List = [['Adam'], ['Vladimir']]
     ]) :-

   filter_on_db(people, [sex], [man]),
   db_select_list(people, _, [name], List).

test(named_args_unify1, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, _, [sex], [man], _),
           ['.', '.']).

test(named_args_unify2, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, _, [sex, sex], [man, man], _),
           ['.', '.']).

test(named_args_unify3_eval, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, _, [sex, age], [_, _], _),
           ['.']).

test(named_args_unify_bug1, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, citizen_v, [sex], [man], _),
           ['.']).

test(named_args_unify_bug2, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, _, [], [], _),
           ['.', '.', '.']).

test(eval_obj_expr1,
     [setup(model_db),
     List == ['Adam', 'Eva', 'Vladimir']]) :-
   findall(Name, @people / name ^= Name, List).

test(eval_obj_expr2, [setup(model_db)]) :-
   findall(Object, ((@people -> Object) / functor ^= citizen_v), Os),
   assertion(Os / surname =^= ['Mayakovsky']).

test(store_and_retrieve1,
    [setup(db_clear(people)),
     man(Sex, Name, Surname, Weight, Height) ==
     man(man, 'Adam', 'Adamov', 1, 3)]
    ) :-

	obj_construct(man_v,
		      [sex, name, surname, weight, height],
		      [man, 'Adam', 'Adamov', 1, 3],
		      Man),

	db_put_object(people, Man, Man1),

	assertion(obj_is_descendant(Man1, db_object_v)),
	assertion(\+ obj_is_descendant(Man1, man_v)),
	assertion(\+ obj_is_descendant(Man, db_object_v)),

	obj_field(Man1, sex, Sex),
	obj_field(Man1, name, Name),
	obj_field(Man1, surname, Surname),
	obj_field(Man1, weight, Weight),
	obj_field(Man1, height, Height).

test(key_rule1,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),
   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']).

test(key_rule2,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v, [], []),
   db_construct(people, man_v, [], []).

test(key_rule3,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v, [name], ['Sergei']),
   db_construct(people, man_v, [], []).

test(key_rule4,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v, [], []),
   db_construct(people, man_v, [name], ['Sergei']).

test(key_rule5, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Sikorsky']).

test(key_rule6,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name], ['Sergei']),

   db_construct(people, man_v,
                [name], ['Sergei']).

test(key_rule7,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name], ['Sergei']),

   db_construct(people, man_v,
                [surname], ['Lodyagin']).

test(key_rule8, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name], ['Sergei']),

   db_construct(people, man_v,
                [name], ['Artem']).

test(key_rule9,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Sysoev']),

   db_construct(people, man_v,
                [name], ['Sergei']).

test(key_rule10,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name], ['Sergei']),

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Sysoev']).

test(key_rule11,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, citizen_v, [], []).

test(key_rule12,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, man_v, [], []).

test(key_rule13,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, man_v, [name], ['James']).

test(key_rule14,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, man_v, [], []),
   db_construct(people, citizen_v, [id], [5]).

test(key_rule15,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, man_v,
                [name, surname], ['James', 'Crick']).

test(key_rule16,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v, [name], ['James']),
   db_construct(people, citizen_v, [id], [4]).

test(key_test1) :-
   obj_construct(c4_v, [a, b, c], [1, 2, 3], A),
   obj_construct(c4_v, [a, b, c], [1, 20, 30], B),
   key_test2(A, B, allow).

% nearest_keymaster(A) = nearest_keymaster(B)
test(key_test_set1) :-

   key_test(c1_v, c2_v).

% nearest_keymaster(A) is_accessor_off nearest_keymaster(B)
test(key_test_set2) :-

   key_test(c1_v, c3_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c1_v, c4_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c1_v, c5_v), % key(nk(A)) = key(nk(B))
   key_test(c1_v, c6_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c1_v, c7_v). % key(nk(A)) instersect key(nk(B)) = {}

% nearest_keymaster(A) is_desc_off nearest_keymaster(B)
test(key_test_set3) :-

   key_test(c4_v, c1_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c3_v, c1_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c5_v, c1_v), % key(nk(A)) = key(nk(B))
   key_test(c6_v, c1_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c7_v, c1_v). % key(nk(A)) instersect key(nk(B)) = {}

% nk(A) no_parent_relation_to nk(B) /\ key(nk(A, B)) = {}
test(key_test_set4_1) :-

   key_test(c1_v, d2_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c1_v, d3_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c1_v, d4_v), % key(nk(A)) = key(nk(B))
   key_test(c1_v, d5_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c1_v, d6_v). % key(nk(A)) instersect key(nk(B)) = {}

% nk(A) no_parent_relation_to nk(B) /\ key(nk(A, B)) /= {}
test(key_test_set4_2) :-

   key_test(c5_v, e2_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c5_v, e3_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c5_v, e4_v), % key(nk(A)) = key(nk(B))
   key_test(c5_v, e5_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c5_v, e6_v). % key(nk(A)) instersect key(nk(B)) = {}

% nk(A) no_parent_relation_to nk(B) /\ key(nk(A, B)) = key(nk(A))
test(key_test_set4_3) :-

   key_test(c5_v, f2_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c5_v, f3_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c5_v, f4_v), % key(nk(A)) = key(nk(B))
   key_test(c5_v, f5_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c5_v, f6_v). % key(nk(A)) instersect key(nk(B)) = {}

% nk(A) no_parent_relation_to nk(B) /\ key(nk(A, B)) = key(nk(B))
test(key_test_set4_4) :-

   key_test(f3_v, c5_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(f2_v, c5_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(f4_v, c5_v), % key(nk(A)) = key(nk(B))
   key_test(f5_v, c5_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(f6_v, c5_v). % key(nk(A)) instersect key(nk(B)) = {}

test(db_properties_v1_overwrite, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),
   db_construct(people, db_properties_v,
                [key_policy], [overwrite]),
   db_construct(people, man_v, [surname], ['Lodyagin']),

   findall([Name, Surname],
           named_args_unify(people, _, [name, surname],
                            [Name, Surname], _),
           List1),
   assertion(List1 =@= [[_, 'Lodyagin']]).

test(db_properties_v2_throw,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),
   db_construct(people, db_properties_v,
                [key_policy], [overwrite]),
   db_construct(people, man_v, [surname], ['Lodyagin']),
   db_construct(people, db_properties_v,
                [key_policy], [throw]),
   db_construct(people, man_v, [name], ['Sergei']).

test(db_properties_v3_fail_ignore, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin'], Obj1),
   db_construct(people, db_properties_v,
                [key_policy], [fail]),
   \+ db_construct(people, man_v, [surname], ['Lodyagin']),

   named_args_unify(people, db_properties_v, [], _, Singl1), !,
   obj_rewrite(Singl1, [key_policy], [fail], [ignore], Singl2),
   db_put_object(people, _, Singl2, _, replaced),

   db_construct(people, man_v,
                [name, surname, height], ['Sergei', 'Lodyagin',
                1.74], Obj2),

   findall([Name, Surname, Height],
           named_args_unify(people, _,
                            [name, surname, height],
                            [Name, Surname, Height], _),
           List1),
   assertion(List1 =@= [['Sergei', 'Lodyagin', _]]),
   assertion(Obj1 =@= Obj2).

test(db_properties_v4_fail_ignore2, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin'], Obj1),
   db_construct(people, db_properties_v,
                [key_policy], [fail]),
   \+ db_construct(people, man_v, [surname], ['Lodyagin']),

   obj_construct(db_properties_v, [key_policy], [ignore], Singl2),
   db_put_object(people, overwrite, Singl2, _),

   db_construct(people, man_v,
                [name, surname, height], ['Sergei', 'Lodyagin',
                1.74], Obj2),

   findall([Name, Surname, Height],
           named_args_unify(people, _,
                            [name, surname, height],
                            [Name, Surname, Height], _),
           List1),
   assertion(List1 =@= [['Sergei', 'Lodyagin', _]]),
   assertion(Obj1 =@= Obj2).

test(db_properties_v5_invalid_policy,
     [setup(db_clear(people)),
      blocked(need_to_see)
      ]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),
   db_construct(people, db_properties_v,
                [key_policy], [throws]),
   db_construct(people, man_v, [surname], ['Lodyagin']).

test(rebase_collision_bug1, [blocked(rebase_collision)]) :-

   obj_construct(man_v, [], [], O0),
   obj_rebase((object_v -> tarjan_vertex_v), O0, O),
   db_put_object(people, O).

% check default key policy
test(after_put_callback1,
     [setup(callback_setup),
      error(db_key_exists(people, _, _))
     ]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),

   context_module(This),
   db_construct(people, db_properties_v,
                [after_put_callback], [This:after_put_callback]),

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']).

test(after_put_callback2,
     [setup(callback_setup)]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),

   context_module(This),
   db_construct(people, db_properties_v,
                [after_put_callback], [This:after_put_callback], Props),

   db_construct(people, man_v,
                [name, surname], ['Alex', 'Petrenko']),

   obj_rewrite(Props, [key_policy], _, [fail], Props2),
   db_put_object(people, _, Props2, Props3, replaced),
   ignore(db_construct(people, man_v,
                       [name, surname], ['Alex', 'Petrenko'])),

   obj_rewrite(Props3, [after_put_callback], _, [_], Props4),
   db_put_object(people, _, Props4, _, replaced),

   db_construct(people, man_v,
                [name, surname], ['James', 'Petrenko']),

   findall(p(Functor, Name, Surname),
           (  apc(Obj),
              obj_unify(Obj, weak,
                        [functor, name, surname], [Functor, Name, Surname])
           ),
           List),

   assertion(List = [p(db_properties_v, _, _),
                     p(man_v, 'Alex', 'Petrenko'),
                     p(db_properties_v, _, _),
                     p(db_properties_v, _, _),
                     p(man_v, 'James', 'Petrenko')
                     ]).

after_put_callback(Obj) :-

   assertz(apc(Obj)).

callback_setup :-

   db_clear(people),
   retractall(apc(_)).

model_db :-

	db_clear(people),
	db_clear(people2),

        db_construct(people, man_v,
                     [sex, name, weight], [man, 'Adam', 73]),
        db_construct(people, man_v,
                     [sex, name, weight], [woman, 'Eva', 64]),

        db_construct(people, citizen_v,
                      [sex, name, surname, country, id],
                      [man, 'Vladimir', 'Mayakovsky',
                       ['Soviet Union'], 1]).

setup :-

   db_clear(plunit_vd__key_test),
   reload_classes.

reload_classes :-

   current_prolog_flag(verbose, Old_Verbose),
   set_prolog_flag(verbose, silent),
   reload_all_classes,
   set_prolog_flag(verbose, Old_Verbose),
   key_test_classes.

key_test_classes :-

   class_create(c0_v, object_v, [a, b, c], [a]),
   class_create(c1_v, c0_v, [], [b, c]),
   class_create(c2_v, c1_v, [d]),
   class_create(c3_v, c2_v, [], [c]),
   class_create(c4_v, c3_v, [], [a, b, c]),
   class_create(c5_v, c1_v, [], [b, c]),
   class_create(c6_v, c1_v, [d], [c, d]),
   class_create(c7_v, c1_v, [e], [a, e]),

   class_create(d1_v, object_v, [a, b, c], [a]),
   class_create(d2_v, d1_v, [], [b]),
   class_create(d3_v, d1_v, [], [a, b, c]),
   class_create(d4_v, d3_v, [], [b, c]),
   class_create(d5_v, d2_v, [], [a, b]),
   class_create(d6_v, d2_v, [f], [c, f]),

   class_create(e1_v, c0_v, [], [b]),
   class_create(e2_v, e1_v, [], [b]),
   class_create(e3_v, e1_v, [], [a, b, c]),
   class_create(e4_v, e3_v, [], [b, c]),
   class_create(e5_v, e2_v, [], [a, b]),
   class_create(e6_v, e2_v, [g], [c, g]),

   class_create(f1_v, c1_v, [], [a]),
   class_create(f2_v, f1_v, [], [b]),
   class_create(f3_v, f1_v, [], [a, b, c]),
   class_create(f4_v, f3_v, [], [b, c]),
   class_create(f5_v, f2_v, [], [a, b]),
   class_create(f6_v, f2_v, [h, j], [j, h]).

key_pattern(patt(Left, Common, Right)) :-
   L = [free, bound],
   member(Left, L),
   member(Common, L),
   member(Right, L).

key_test(AC, BC) :-
   class_primary_id(AC, Id1),
   class_primary_id(BC, Id2),
   nearest_common_keymaster_int(Id1, Id2, Keymaster_Id),
   forall(
          key_pattern(Patt),
          (   fill_keys(AC, BC, Keymaster_Id, Patt, A, B),
              assertion(key_test2(A, B))
	  )).

% Calculate the result
key_test_result(A, B, allow) :-
   ( obj_key(A, []) ; obj_key(B, [])), !.
key_test_result(A, B, conflict) :-
   arg(1, A, Id1),
   arg(1, B, Id2),
   nearest_common_keymaster_int(Id1, Id2, Keymaster_Id),
   get_key(Keymaster_Id, K_Key),
   K_Key \= [],
   obj_unify(A, K_Key, Value),
   obj_unify(B, K_Key, Value), !.
key_test_result(_, _, allow).

key_test2(A, B) :-
   key_test_result(A, B, Conflict),
   key_test2(A, B, Conflict).

key_test2(A, B, allow) :-
   DB = plunit_vd__key_test,
   db_clear(DB),
   db_put_object(DB, A),
   db_put_object(DB, fail, B, _),
   db_clear(DB),
   db_put_object(DB, B),
   db_put_object(DB, fail, A, _), !.

key_test2(A, B, conflict) :-
   DB = plunit_vd__key_test,
   db_clear(DB),
   db_put_object(DB, A),
   \+ db_put_object(DB, fail, B, _),
   db_clear(DB),
   db_put_object(DB, B),
   \+ db_put_object(DB, fail, A, _).

fill_keys(AC, BC, Keymaster_Id, Patt, A, B) :-
   get_key(Keymaster_Id, Common_Key_Part),
   obj_construct(AC, [], [], A),
   obj_construct(BC, [], [], B),
   fill_key(Patt, Common_Key_Part, A, B).

fill_key(patt(A_Patt, Common_Patt, B_Patt), Common_Key, A, B) :-
   obj_key(A, A_Key),
   obj_unify(A, A_Key, A_Key_Value),
   fill_key(A_Patt, A_Key, A_Key_Value),
   obj_unify(A, Common_Key, Common_Key_Value),
   fill_key(Common_Patt, Common_Key, Common_Key_Value),
   obj_key(B, B_Key),
   obj_unify(B, B_Key, B_Key_Value),
   fill_key(B_Patt, B_Key, B_Key_Value).

fill_key(bound, Key, Key) :- !.
fill_key(half_bound, [K|KT], [K|KVT]) :- !,
   same_length(KT, KVT).
fill_key(free, Key, Key_Value) :-
   same_length(Key, Key_Value).

:- end_tests(vd).

:- begin_tests(vd, [setup(setup)]).

:- multifile prolog:message//1.

:- use_module(u(v)).
:- use_module(u(vd)).
:- use_module(u(internal/db_i)).
:- use_module(u(internal/objects_i)).
:- use_module(u(util/lambda)).
:- use_module(library(aggregate)).
:- use_module(library(ordsets)).

test(clear_test_db, [fail, setup(db_clear(people))]) :-

	db_recorded(people, _).

test(db_clear, [setup(model_db), List == []]) :-

   reload_classes,

   % clear all DBs with citizen_v
   (  db_name(DB_Key),
      (  named_args_unify(DB_Key, citizen_v, [], [], _)
      -> db_clear(DB_Key)
      ;  true
      ),
      fail ; true
   ),

   findall(X,
           (db_i:current_predicate(citizen_v, X), call(db_i:X)),
           List).

test(db_copy, [setup(model_db), N =:= 3]) :-

   db_copy(people, people2),
   findall('.', db_recorded(people2, _), L),
   length(L, N).

test(db_erase1, [setup(model_db)]) :-
   (  named_args_unify(people, _,
                       [weight, surname], [73, _], X),
      db_erase(X),
      fail ; true
   ),
   findall(Y,
           db_recorded(people, Y),
           LY),
   assertion(LY = [man_v(_, _, _, _, _, 'Eva', woman, _, _)]).

test(db_erase2, [setup(db_clear(people))]) :-
   db_construct(people, citizen_v,
                [birthday, sex],
                [1994, man], C1),
   db_size(people, S1),
   assertion(S1 == 1),
   obj_downcast(C1, C2),
   functor(C2, CC, _),
   assertion(CC == callup_v),
   db_erase(C2),
   db_size(people, S2),
   assertion(S2 == 0).

test(db_iterate1, [setup(model_db), N =:= 3]) :-

   findall('.', db_iterate(people, true, _), L),
   length(L, N).

test(db_iterate2, [setup(model_db), N =:= 2]) :-

   findall(O, db_iterate(people, sex(man), O), L),
   length(L, N).

test(db_iterate3, [setup(model_db), fail]) :-

   db_iterate(people, unexisting_name(man_v), _).

test(db_iterate4, [setup(model_db), N =:= 2]) :-

   findall(O, db_iterate(people, functor(man_v), O), L),
   length(L, N).

test(db_iterate5, [setup(model_db), N =:= 3]) :-

   findall(O, db_iterate(people, functor(_), O), L),
   length(L, N).

test(db_iterate6, [setup(model_db), N =:= 3]) :-

   findall(O, db_iterate(people, same_or_descendant(man_v), O), L),
   length(L, N).

test(db_iterate7, [setup(model_db), N =:= 1]) :-

   findall(O, db_iterate(people, same_or_descendant(citizen_v), O), L),
   length(L, N).

test(db_iterate8, [setup(model_db)]) :-

   findall(Surname, db_iterate(people, surname(Surname), _), SL),
   assertion(SL =@= [_, _, 'Mayakovsky']),
   findall(Surname, db_iterate(people, sex(Surname), _), SL2),
   assertion(SL2 == [man, woman, man]).

test(db_iterate9, [setup(model_db), N == 1]) :-

   aggregate_all(count, db_iterate(people, surname(+bound), _), N).

test(db_iterate10, [setup(model_db), N == 2]) :-

   aggregate_all(count, db_iterate(people, surname(+free), _), N).

test(db_iterate11, [setup(model_db)]) :-

   aggregate_all(count,
                 db_iterate(people,
                            surname('Mayakovsky') /\ surname(+free), _),
                 N1),
   assertion(N1 == 0),
   aggregate_all(count,
                 db_iterate(people,
                            surname(+free) /\ surname('Mayakovsky'), _),
                 N2),
   assertion(N2 == 0),
   aggregate_all(count,
                 db_iterate(people,
                            surname(+free) /\ surname(+bound), _),
                 N3),
   assertion(N3 == 0),
   aggregate_all(count,
                 db_iterate(people,
                            surname(+free) \/ surname(+bound), _),
                 N4),
   assertion(N4 == 3),
   aggregate_all(count,
                 db_iterate(people,
                            surname('Mayakovsky') /\ surname(+bound), _),
                 N5),
   assertion(N5 == 1),
   aggregate_all(count,
                 db_iterate(people,
                            surname(+bound) /\ surname('Mayakovsky'), _),
                 N6),
   assertion(N6 == 1).

test(db_to_list, [setup(model_db)]) :-

   db_to_list(people, man_v, L1),
   length(L1, N1),
   assertion(N1 =:= 2),

   db_to_list(people, citizen_v, L2),
   length(L2, N2),
   assertion(N2 =:= 1),

   db_to_list(people, _, L3),
   length(L3, N3),
   assertion(N3 =:= 3).

test(db_put_object1,
     [setup(model_db),
      List == [['Adam'], ['Eva'], ['Moses'], ['Vladimir']]
      ]) :-

   obj_construct(man_v, [name], ['Moses'], Man),
   db_put_object(people, Man),
   db_select_list(people, _, [name], List).

test(db_put_object2, [setup(model_db)]) :-

   obj_construct(man_v, [name], ['Moses'], Man0),
   obj_rebase((object_v -> db_object_v), Man0, Man),
   db_put_object(people, Man).

test(db_put_object3,
     [setup(model_db),
      error(db_obj_replace_protector(people2, _, Man))]) :-

   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man), !,
   db_put_object(people2, Man).

test(db_put_object4, [setup(model_db)]) :-
% replacing

   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_rewrite(Man0, [name], ['Moses'], [_], Man1),
   db_put_object(people2, throw, Man1, Man2, Replaced),
   named_args_unify(Man2,
                    [name, db_key, db_ref],
                    [New_Name, DB_Key, DB_Ref]),
   assertion(New_Name =@= _),
   assertion(Replaced == replaced),
   assertion(nonvar(DB_Ref)),
   assertion(DB_Key == people2),

   db_size(people2, N),
   assertion(N =:= 1).

% replacing rebased
test(db_put_object4_1, [setup(model_db), error(class_parents_mismatch(_,_,_,_))]) :-
   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_rewrite(Man0, [name], ['Moses'], [_], Man1),
   obj_parents(Man1, [man_v, tarjan_vertex_v, db_object_v, object_v, object_base_v], Man2),
   db_put_object(people2, throw, Man2, _, _).

% replacing downcasted
test(db_put_object4_2, [setup(db_clear(people2))]) :-
   db_construct(people2, citizen_v,
                [birthday, sex, name, surname, id],
                [1994, man, l, k, 199442]),
   db_recorded(people2, Man1), !,
   obj_downcast(Man1, callup_v, Man2),
   db_put_object(people2, throw, Man2, Man3, Replaced),
   named_args_unify(Man3,
                    [name, db_key, db_ref],
                    [New_Name, DB_Key, DB_Ref]),
   assertion(New_Name == l),
   assertion(Replaced == replaced),
   assertion(nonvar(DB_Ref)),
   assertion(DB_Key == people2),
   db_size(people2, N),
   assertion(N =:= 1).

test(db_put_object5,
     [setup(model_db),
      error(domain_error(unbound_db_ref, DB_Ref))]) :-

   db_construct(people, man_v, [name], ['Moses']),
   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_field(Man0, db_ref, DB_Ref),
   db_put_object(people, throw, Man0, _, _).

test(db_put_object6,
     [setup(model_db),
      error(domain_error(unbound_or_same_db_key, people2))]) :-

   db_construct(people, man_v, [name], ['Moses']),
   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_reset_fields([db_ref], Man0, Man),
   db_put_object(people, throw, Man, _, _).

test(db_put_object7,
     [setup(model_db),
      error(db_obj_replace_protector(people2, replaced, Man1))]) :-

   db_construct(people2, man_v, [name], ['Moses']),
   db_recorded(people2, Man0), !,
   obj_rewrite(Man0, [db_ref, name], [_, 'Moses'], [_, _], Man1),
   db_put_object(people2, throw, Man1, _, replaced).
   % does not replace because of unbound db_ref

test(db_put_object8,
     [setup(model_db),
      error(db_obj_replace_protector(people2, replaced, Man))]) :-

   db_construct(people2, man_v, [name], ['Moses']),
   obj_construct(man_v, [name], ['Simeon'], Man),
   db_put_object(people2, _, Man, _, replaced).
   % does not replace because of not db_object_v descendant

test(db_put_object9,
     [blocked(rebase_collision), setup(model_db),
      List == [['Adam'], ['Eva'], ['Moses'], ['Vladimir']]
      ]) :-

   obj_construct(man_v, [name], ['Moses'], Man0),
   obj_rebase((object_v -> db_object_v), Man0, Man1),
   obj_rebase((object_v -> tarjan_vertex_v), Man1, Man),
   db_put_object(people, Man),
   db_select_list(people, _, [name], List).

test(db_recorda1,
     [setup(model_db),
      List == [['Moses'], ['Adam'], ['Eva'], ['Vladimir']]
      ]) :-

   obj_construct(man_v, [name], ['Moses'], Man),
   db_recorda(people, Man),
   db_select_list(people, _, [name], List).

test(db_put_objects,
    [setup(db_clear(people)),
     DB_Size =:= 3]
    ) :-

	maplist(obj_construct(man_v, [name]),
		[['Valera'], ['Vika'], ['Yura']],
		Men),

	db_put_objects(people,
		       Men+\El^member(El, Men),
		       fail),

	db_size(people, DB_Size).

test(db_recorded_bug1, [setup(model_db), N =:= 3]) :-

   findall('.', db_recorded(people, _), L),
   length(L, N).

test(db_recorded1,
     [setup(model_db),
      error(domain_error(db_object_v_descendant, X))]) :-

   obj_construct(man_v, [sex], [man], X),
   db_recorded(people, X).

test(db_recorded2, [setup(model_db)]) :-

   findall('.',
           (obj_construct(man_v, [sex], [man], X0),
            obj_rebase((object_v -> db_object_v), X0, X),
            db_recorded(people, X)),
           L2),
   length(L2, N2),
   assertion(N2 =:= 1).

test(db_recorded3, [setup(model_db)]) :-

   findall('.',
           (obj_construct(man_v, [], [], X0),
            obj_rebase((object_v -> db_object_v), X0, X),
            db_recorded(people, X)),
           L2),
   length(L2, N2),
   assertion(N2 =:= 2).

test(db_recorded4, [setup(model_db)]) :-

   findall('.',
           (obj_construct(man_v, [height], [1.76], X0),
            obj_rebase((object_v -> db_object_v), X0, X),
            db_recorded(people, X)),
           L2),
   length(L2, N2),
   assertion(N2 =:= 2).

test(db_recorded5, [setup(db_clear(people))]) :-

   db_construct(people, man_v, [], []),
   db_recorded(people, X), !,
   db_recorded(people, X).

% test(db_rewrite1,
%      [setup(model_db),
%       List =@= [['Adam', 'Kasperski', 66],
%                 ['Eva', 'Kasperski', 66],
%                 ['Vladimir', 'Kasperski', 66]]
%      ]) :-

%    db_rewrite(people, _,
%               [weight, surname], _, [66, 'Kasperski']),
%    db_select_list(people, _, [name, surname, weight], List).

% test(db_rewrite2,
%      [setup(model_db),
%       List =@= [['Adam', 'Kasperski', 66],
%                 ['Eva', 'Kasperski', 66],
%                 ['Vladimir', 'Mayakovsky', _]]
%      ]) :-

%    db_rewrite(people, man_v,
%               [weight, surname], _, [66, 'Kasperski']),
%    db_select_list(people, _, [name, surname, weight], List).

test(db_search,
     [setup(model_db),
      List == [['Adam'], ['Vladimir']]
     ]) :-

   db_search(people, people2, db_search_pred),
   db_select_list(people2, _, [name], List).

db_search_pred(Man) :-

  obj_field(Man, sex, Sex),
  Sex == man.

test(db_select1,
     [setup(model_db),
      List =@= [[man_v, man, 'Adam', _, 73, _],
                [man_v, woman, 'Eva', _, 64, _],
                [citizen_v, man, 'Vladimir', 'Mayakovsky', _,
                 ['Soviet Union']]]
      ]) :-

   findall(Row,
           db_select(people,
                     [class, sex, name, surname, weight, country],
                     Row),
           List
          ).

test(db_select2,
     [setup(model_db),
      List =@= [[man_v, man, 'Adam', _, 73, _],
                [man_v, woman, 'Eva', _, 64, _]]
      ]) :-

   findall(Row,
           (   Row = [man_v|_],
               db_select(people,
                         [functor, sex, name, surname, weight,
                          country],
                         Row)
           ), List
          ).

test(db_select3,
     [setup((model_db,
      db_construct(people, citizen_v, [id, sex, name, age], [2, man, 'Igor', 19]))),
     Classes == [callup_v]]) :-
   findall(Class, db_select(people,  [name, class], ['Igor', Class]), Classes).

test(db_select_list1,
     [setup(model_db),
      List =@= [[man_v, man, 'Adam', _, 73, _],
                [man_v, woman, 'Eva', _, 64, _],
                [citizen_v, man, 'Vladimir', 'Mayakovsky', _,
                 ['Soviet Union']]]
      ]) :-

   db_select_list(people, _,
                  [class, sex, name, surname, weight, country],
                  List).

test(db_select_list2,
     [setup(model_db),
      List =@= [[man_v, man, 'Adam', _, 73, _],
                [man_v, woman, 'Eva', _, 64, _]]
      ]) :-

   db_select_list(people, man_v, _,
                  [class, sex, name, surname, weight, country],
                  List).

test(db_select_list3,
     [setup(model_db),
      error(no_object_field(_, country))
      ]) :-

   db_select_list(people, man_v, throw,
                  [class, sex, name, surname, weight, country],
                  _).

test(filter_on_db,
     [setup(model_db),
      List = [['Adam'], ['Vladimir']]
     ]) :-

   filter_on_db(people, [sex], [man]),
   db_select_list(people, _, [name], List).

test(named_args_unify1, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, _, [sex], [man], _),
           ['.', '.']).

test(named_args_unify2, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, _, [sex, sex], [man, man], _),
           ['.', '.']).

test(named_args_unify3_eval, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, _, [sex, age], [_, _], _),
           ['.']).

test(named_args_unify_bug1, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, citizen_v, [sex], [man], _),
           ['.']).

test(named_args_unify_bug2, [setup(model_db)]) :-

   findall('.',
           named_args_unify(people, _, [], [], _),
           ['.', '.', '.']).

test(eval_obj_expr1,
     [setup(model_db),
     List == ['Adam', 'Eva', 'Vladimir']]) :-
   findall(Name, @people / name ^= Name, List).

test(eval_obj_expr2, [setup(model_db)]) :-
   findall(Object, ((@people -> Object) / functor ^= citizen_v), Os),
   assertion(Os / surname =^= ['Mayakovsky']).

test(store_and_retrieve1,
    [setup(db_clear(people)),
     man(Sex, Name, Surname, Weight, Height) ==
     man(man, 'Adam', 'Adamov', 1, 3)]
    ) :-

	obj_construct(man_v,
		      [sex, name, surname, weight, height],
		      [man, 'Adam', 'Adamov', 1, 3],
		      Man),

	db_put_object(people, Man, Man1),

	assertion(obj_is_descendant(Man1, db_object_v)),
	assertion(\+ obj_is_descendant(Man1, man_v)),
	assertion(\+ obj_is_descendant(Man, db_object_v)),

	obj_field(Man1, sex, Sex),
	obj_field(Man1, name, Name),
	obj_field(Man1, surname, Surname),
	obj_field(Man1, weight, Weight),
	obj_field(Man1, height, Height).

test(key_rule1,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),
   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']).

test(key_rule2,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v, [], []),
   db_construct(people, man_v, [], []).

test(key_rule3,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v, [name], ['Sergei']),
   db_construct(people, man_v, [], []).

test(key_rule4,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v, [], []),
   db_construct(people, man_v, [name], ['Sergei']).

test(key_rule5, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Sikorsky']).

test(key_rule6,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name], ['Sergei']),

   db_construct(people, man_v,
                [name], ['Sergei']).

test(key_rule7,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name], ['Sergei']),

   db_construct(people, man_v,
                [surname], ['Lodyagin']).

test(key_rule8, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name], ['Sergei']),

   db_construct(people, man_v,
                [name], ['Artem']).

test(key_rule9,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Sysoev']),

   db_construct(people, man_v,
                [name], ['Sergei']).

test(key_rule10,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name], ['Sergei']),

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Sysoev']).

test(key_rule11,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, citizen_v, [], []).

test(key_rule12,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, man_v, [], []).

test(key_rule13,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, man_v, [name], ['James']).

test(key_rule14,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, man_v, [], []),
   db_construct(people, citizen_v, [id], [5]).

test(key_rule15,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, citizen_v, [id], [4]),
   db_construct(people, man_v,
                [name, surname], ['James', 'Crick']).

test(key_rule16,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v, [name], ['James']),
   db_construct(people, citizen_v, [id], [4]).

test(key_test1) :-
   obj_construct(c4_v, [a, b, c], [1, 2, 3], A),
   obj_construct(c4_v, [a, b, c], [1, 20, 30], B),
   key_test2(A, B, allow).

% nearest_keymaster(A) = nearest_keymaster(B)
test(key_test_set1) :-

   key_test(c1_v, c2_v).

% nearest_keymaster(A) is_accessor_off nearest_keymaster(B)
test(key_test_set2) :-

   key_test(c1_v, c3_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c1_v, c4_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c1_v, c5_v), % key(nk(A)) = key(nk(B))
   key_test(c1_v, c6_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c1_v, c7_v). % key(nk(A)) instersect key(nk(B)) = {}

% nearest_keymaster(A) is_desc_off nearest_keymaster(B)
test(key_test_set3) :-

   key_test(c4_v, c1_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c3_v, c1_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c5_v, c1_v), % key(nk(A)) = key(nk(B))
   key_test(c6_v, c1_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c7_v, c1_v). % key(nk(A)) instersect key(nk(B)) = {}

% nk(A) no_parent_relation_to nk(B) /\ key(nk(A, B)) = {}
test(key_test_set4_1) :-

   key_test(c1_v, d2_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c1_v, d3_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c1_v, d4_v), % key(nk(A)) = key(nk(B))
   key_test(c1_v, d5_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c1_v, d6_v). % key(nk(A)) instersect key(nk(B)) = {}

% nk(A) no_parent_relation_to nk(B) /\ key(nk(A, B)) /= {}
test(key_test_set4_2) :-

   key_test(c5_v, e2_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c5_v, e3_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c5_v, e4_v), % key(nk(A)) = key(nk(B))
   key_test(c5_v, e5_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c5_v, e6_v). % key(nk(A)) instersect key(nk(B)) = {}

% nk(A) no_parent_relation_to nk(B) /\ key(nk(A, B)) = key(nk(A))
test(key_test_set4_3) :-

   key_test(c5_v, f2_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(c5_v, f3_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(c5_v, f4_v), % key(nk(A)) = key(nk(B))
   key_test(c5_v, f5_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(c5_v, f6_v). % key(nk(A)) instersect key(nk(B)) = {}

% nk(A) no_parent_relation_to nk(B) /\ key(nk(A, B)) = key(nk(B))
test(key_test_set4_4) :-

   key_test(f3_v, c5_v), % key(nk(A)) is_superset_of key(nk(B))
   key_test(f2_v, c5_v), % key(nk(A)) is_subset_of key(nk(B))
   key_test(f4_v, c5_v), % key(nk(A)) = key(nk(B))
   key_test(f5_v, c5_v), % key(nk(A)) instersect key(nk(B)) /= {}
   key_test(f6_v, c5_v). % key(nk(A)) instersect key(nk(B)) = {}

test(db_properties_v1_overwrite, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),
   db_construct(people, db_properties_v,
                [key_policy], [overwrite]),
   db_construct(people, man_v, [surname], ['Lodyagin']),

   findall([Name, Surname],
           named_args_unify(people, _, [name, surname],
                            [Name, Surname], _),
           List1),
   assertion(List1 =@= [[_, 'Lodyagin']]).

test(db_properties_v2_throw,
     [setup(db_clear(people)),
      error(db_key_exists(people, _, _))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),
   db_construct(people, db_properties_v,
                [key_policy], [overwrite]),
   db_construct(people, man_v, [surname], ['Lodyagin']),
   db_construct(people, db_properties_v,
                [key_policy], [throw]),
   db_construct(people, man_v, [name], ['Sergei']).

test(db_properties_v3_fail_ignore, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin'], Obj1),
   db_construct(people, db_properties_v,
                [key_policy], [fail]),
   \+ db_construct(people, man_v, [surname], ['Lodyagin']),

   named_args_unify(people, db_properties_v, [], _, Singl1), !,
   obj_rewrite(Singl1, [key_policy], [fail], [ignore], Singl2),
   db_put_object(people, _, Singl2, _, replaced),

   db_construct(people, man_v,
                [name, surname, height], ['Sergei', 'Lodyagin',
                1.74], Obj2),

   findall([Name, Surname, Height],
           named_args_unify(people, _,
                            [name, surname, height],
                            [Name, Surname, Height], _),
           List1),
   assertion(List1 =@= [['Sergei', 'Lodyagin', _]]),
   assertion(Obj1 =@= Obj2).

test(db_properties_v4_fail_ignore2, [setup(db_clear(people))]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin'], Obj1),
   db_construct(people, db_properties_v,
                [key_policy], [fail]),
   \+ db_construct(people, man_v, [surname], ['Lodyagin']),

   obj_construct(db_properties_v, [key_policy], [ignore], Singl2),
   db_put_object(people, overwrite, Singl2, _),

   db_construct(people, man_v,
                [name, surname, height], ['Sergei', 'Lodyagin',
                1.74], Obj2),

   findall([Name, Surname, Height],
           named_args_unify(people, _,
                            [name, surname, height],
                            [Name, Surname, Height], _),
           List1),
   assertion(List1 =@= [['Sergei', 'Lodyagin', _]]),
   assertion(Obj1 =@= Obj2).

test(db_properties_v5_invalid_policy,
     [setup(db_clear(people)),
      blocked(need_to_see)
      ]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),
   db_construct(people, db_properties_v,
                [key_policy], [throws]),
   db_construct(people, man_v, [surname], ['Lodyagin']).

test(rebase_collision_bug1, [blocked(rebase_collision)]) :-

   obj_construct(man_v, [], [], O0),
   obj_rebase((object_v -> tarjan_vertex_v), O0, O),
   db_put_object(people, O).

% check default key policy
test(after_put_callback1,
     [setup(callback_setup),
      error(db_key_exists(people, _, _))
     ]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),

   context_module(This),
   db_construct(people, db_properties_v,
                [after_put_callback], [This:after_put_callback]),

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']).

test(after_put_callback2,
     [setup(callback_setup)]) :-

   db_construct(people, man_v,
                [name, surname], ['Sergei', 'Lodyagin']),

   context_module(This),
   db_construct(people, db_properties_v,
                [after_put_callback], [This:after_put_callback], Props),

   db_construct(people, man_v,
                [name, surname], ['Alex', 'Petrenko']),

   obj_rewrite(Props, [key_policy], _, [fail], Props2),
   db_put_object(people, _, Props2, Props3, replaced),
   ignore(db_construct(people, man_v,
                       [name, surname], ['Alex', 'Petrenko'])),

   obj_rewrite(Props3, [after_put_callback], _, [_], Props4),
   db_put_object(people, _, Props4, _, replaced),

   db_construct(people, man_v,
                [name, surname], ['James', 'Petrenko']),

   findall(p(Functor, Name, Surname),
           (  apc(Obj),
              obj_unify(Obj, weak,
                        [functor, name, surname], [Functor, Name, Surname])
           ),
           List),

   assertion(List = [p(db_properties_v, _, _),
                     p(man_v, 'Alex', 'Petrenko'),
                     p(db_properties_v, _, _),
                     p(db_properties_v, _, _),
                     p(man_v, 'James', 'Petrenko')
                     ]).

after_put_callback(Obj) :-

   assertz(apc(Obj)).

callback_setup :-

   db_clear(people),
   retractall(apc(_)).

model_db :-

	db_clear(people),
	db_clear(people2),

        db_construct(people, man_v,
                     [sex, name, weight], [man, 'Adam', 73]),
        db_construct(people, man_v,
                     [sex, name, weight], [woman, 'Eva', 64]),

        db_construct(people, citizen_v,
                      [sex, name, surname, country, id],
                      [man, 'Vladimir', 'Mayakovsky',
                       ['Soviet Union'], 1]).

setup :-

   db_clear(plunit_vd__key_test),
   reload_classes.

reload_classes :-

   current_prolog_flag(verbose, Old_Verbose),
   set_prolog_flag(verbose, silent),
   reload_all_classes,
   set_prolog_flag(verbose, Old_Verbose),
   key_test_classes.

key_test_classes :-

   class_create(c0_v, object_v, [a, b, c], [a]),
   class_create(c1_v, c0_v, [], [b, c]),
   class_create(c2_v, c1_v, [d]),
   class_create(c3_v, c2_v, [], [c]),
   class_create(c4_v, c3_v, [], [a, b, c]),
   class_create(c5_v, c1_v, [], [b, c]),
   class_create(c6_v, c1_v, [d], [c, d]),
   class_create(c7_v, c1_v, [e], [a, e]),

   class_create(d1_v, object_v, [a, b, c], [a]),
   class_create(d2_v, d1_v, [], [b]),
   class_create(d3_v, d1_v, [], [a, b, c]),
   class_create(d4_v, d3_v, [], [b, c]),
   class_create(d5_v, d2_v, [], [a, b]),
   class_create(d6_v, d2_v, [f], [c, f]),

   class_create(e1_v, c0_v, [], [b]),
   class_create(e2_v, e1_v, [], [b]),
   class_create(e3_v, e1_v, [], [a, b, c]),
   class_create(e4_v, e3_v, [], [b, c]),
   class_create(e5_v, e2_v, [], [a, b]),
   class_create(e6_v, e2_v, [g], [c, g]),

   class_create(f1_v, c1_v, [], [a]),
   class_create(f2_v, f1_v, [], [b]),
   class_create(f3_v, f1_v, [], [a, b, c]),
   class_create(f4_v, f3_v, [], [b, c]),
   class_create(f5_v, f2_v, [], [a, b]),
   class_create(f6_v, f2_v, [h, j], [j, h]).

key_pattern(patt(Left, Common, Right)) :-
   L = [free, bound],
   member(Left, L),
   member(Common, L),
   member(Right, L).

key_test(AC, BC) :-
   class_primary_id(AC, Id1),
   class_primary_id(BC, Id2),
   nearest_common_keymaster_int(Id1, Id2, Keymaster_Id),
   forall(
          key_pattern(Patt),
          (   fill_keys(AC, BC, Keymaster_Id, Patt, A, B),
              assertion(key_test2(A, B))
	  )).

% Calculate the result
key_test_result(A, B, allow) :-
   ( obj_key(A, []) ; obj_key(B, [])), !.
key_test_result(A, B, conflict) :-
   arg(1, A, Id1),
   arg(1, B, Id2),
   nearest_common_keymaster_int(Id1, Id2, Keymaster_Id),
   get_key(Keymaster_Id, K_Key),
   K_Key \= [],
   obj_unify(A, K_Key, Value),
   obj_unify(B, K_Key, Value), !.
key_test_result(_, _, allow).

key_test2(A, B) :-
   key_test_result(A, B, Conflict),
   key_test2(A, B, Conflict).

key_test2(A, B, allow) :-
   DB = plunit_vd__key_test,
   db_clear(DB),
   db_put_object(DB, A),
   db_put_object(DB, fail, B, _),
   db_clear(DB),
   db_put_object(DB, B),
   db_put_object(DB, fail, A, _), !.

key_test2(A, B, conflict) :-
   DB = plunit_vd__key_test,
   db_clear(DB),
   db_put_object(DB, A),
   \+ db_put_object(DB, fail, B, _),
   db_clear(DB),
   db_put_object(DB, B),
   \+ db_put_object(DB, fail, A, _).

fill_keys(AC, BC, Keymaster_Id, Patt, A, B) :-
   get_key(Keymaster_Id, Common_Key_Part),
   obj_construct(AC, [], [], A),
   obj_construct(BC, [], [], B),
   fill_key(Patt, Common_Key_Part, A, B).

fill_key(patt(A_Patt, Common_Patt, B_Patt), Common_Key, A, B) :-
   obj_key(A, A_Key),
   obj_unify(A, A_Key, A_Key_Value),
   fill_key(A_Patt, A_Key, A_Key_Value),
   obj_unify(A, Common_Key, Common_Key_Value),
   fill_key(Common_Patt, Common_Key, Common_Key_Value),
   obj_key(B, B_Key),
   obj_unify(B, B_Key, B_Key_Value),
   fill_key(B_Patt, B_Key, B_Key_Value).

fill_key(bound, Key, Key) :- !.
fill_key(half_bound, [K|KT], [K|KVT]) :- !,
   same_length(KT, KVT).
fill_key(free, Key, Key_Value) :-
   same_length(Key, Key_Value).

:- end_tests(vd).


sometimes, for debugging, preprocessed output may be helpful

git-svn-id: 4e7379b20b57f8e3dde5a0b7363f233184647162@806 4e380d45-d1fd-0310-85a7-d18ec86df0ad

# This -*- Makefile -*- is intended for processing with GNU make.

TOPDIR	?= $(error TOPDIR not defined) # DO NOT CHANGE! This is set elsewhere.

# Change this file according to your paths.

# Instead of modifying this file, you could also set your modified variables
# in make.settings.local (needs to be created first).
-include $(TOPDIR)/make.settings.local

USE_BOOST	?= no	# set 'yes' to use Boost libraries or 'no' to not use Boost libraries
USE_LINUX	?= yes	# set 'yes' if you run Linux, 'no' otherwise
USE_MCSTL	?= no	# will be overriden from main Makefile
USE_ICPC	?= no	# will be overriden from main Makefile

STXXL_ROOT	?= $(HOME)/work/stxxl

ifeq ($(strip $(USE_ICPC)),yes)
COMPILER_ICPC	?= icpc
COMPILER	?= $(COMPILER_ICPC)
#ICPC_GCC	?= gcc-x.y    # override the gcc/g++ used to find headers and libraries
WARNINGS	?= -Wall -w1 -openmp-report0 -vec-report0
endif

ifeq ($(strip $(USE_MCSTL)),yes)
COMPILER_GCC	?= g++-4.2.3
LIBNAME		?= mcstxxl
# the root directory of your MCSTL installation
MCSTL_ROOT	?= $(HOME)/work/mcstl
endif

#BOOST_ROOT	?= /usr/local/boost-1.34.1

COMPILER_GCC	?= g++
COMPILER	?= $(COMPILER_GCC)
LINKER		?= $(COMPILER)
OPT		?= -O3 # compiler optimization level
WARNINGS	?= -W -Wall
DEBUG		?= # put here -g option to include the debug information into the binaries

LIBNAME		?= stxxl

#### TROUBLESHOOTING
#
# For automatical checking of order of the output elements in
# the sorters: stxxl::stream::sort, stxxl::stream::merge_runs,
# stxxl::sort, and stxxl::ksort use
#
#STXXL_SPECIFIC	+= -DSTXXL_CHECK_ORDER_IN_SORTS
#
# If your program aborts with message "read/write: wrong parameter"
# or "Invalid argument"
# this could be that your kernel does not support direct I/O
# then try to set it off recompiling the libs and your code with option
#
#STXXL_SPECIFIC	+= -DSTXXL_DIRECT_IO_OFF
#
# But for the best performance it is strongly recommended
# to reconfigure the kernel for the support of the direct I/O.
#
# FIXME: documentation needed
#
#STXXL_SPECIFIC += -DSTXXL_DEBUGMON

#### You usually shouldn't need to change the sections below #####

#### STXXL OPTIONS ###############################################

# check, whether stxxl has been configured
ifeq (,$(strip $(wildcard $(STXXL_ROOT)/include/stxxl.h)))
$(warning *** WARNING: STXXL has not been configured correctly)
ifeq (,$(strip $(wildcard $(CURDIR)/make.settings.local)))
ifneq (,$(strip $(wildcard $(CURDIR)/include/stxxl.h)))
$(warning *** WARNING: trying autoconfiguration for STXXL_ROOT=$(CURDIR:$(HOME)%=$$(HOME)%))
$(warning *** WARNING: you did not have a make.settings.local file -- creating ...)
$(shell echo 'STXXL_ROOT	 = $(CURDIR:$(HOME)%=$$(HOME)%)' >> $(CURDIR)/make.settings.local)
MCSTL_ROOT	?= $(HOME)/work/mcstl
$(shell echo '#MCSTL_ROOT	 = $(MCSTL_ROOT:$(HOME)%=$$(HOME)%)' >> $(CURDIR)/make.settings.local)
$(shell echo '#COMPILER_GCC	 = g++-4.2.3' >> $(CURDIR)/make.settings.local)
$(shell echo '#COMPILER_ICPC	 = icpc' >> $(CURDIR)/make.settings.local)
$(error ERROR: Please check make.settings.local and try again)
endif
else
$(warning *** WARNING: Please check make.settings.local)
endif
$(error ERROR: could not find a STXXL installation in STXXL_ROOT=$(STXXL_ROOT))
endif

# in the top dir, check whether STXXL_ROOT points to ourselves
ifneq (,$(wildcard make.settings))
stat1	 = $(shell stat -L -c '%d:%i' ./)
stat2	 = $(shell stat -L -c '%d:%i' $(STXXL_ROOT)/)

ifneq ($(stat1),$(stat2))
$(error ERROR: STXXL_ROOT=$(STXXL_ROOT) points to a different STXXL installation)
endif
endif

PTHREAD_FLAG	?= -pthread

STXXL_SPECIFIC	+= \
	$(PTHREAD_FLAG) \
	$(CPPFLAGS_ARCH) \
	-DSORT_OPTIMAL_PREFETCHING \
	-DUSE_MALLOC_LOCK \
	-DCOUNT_WAIT_TIME \
	-I$(strip $(STXXL_ROOT))/include \
	-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
	$(POSIX_MEMALIGN) $(XOPEN_SOURCE)

STXXL_LDFLAGS	+= $(PTHREAD_FLAG)
STXXL_LDLIBS	+= -L$(strip $(STXXL_ROOT))/lib -l$(LIBNAME)

STXXL_LIBDEPS	+= $(strip $(STXXL_ROOT))/lib/lib$(LIBNAME).$(LIBEXT)

UNAME_M		:= $(shell uname -m)
CPPFLAGS_ARCH	+= $(CPPFLAGS_$(UNAME_M))
CPPFLAGS_i686	?= -march=i686

##################################################################

#### ICPC OPTIONS ################################################

ifeq ($(strip $(USE_ICPC)),yes)

OPENMPFLAG	?= -openmp

ICPC_CPPFLAGS	+= $(if $(ICPC_GCC),-gcc-name=$(strip $(ICPC_GCC)))
ICPC_LDFLAGS	+= $(if $(ICPC_GCC),-gcc-name=$(strip $(ICPC_GCC)))

STXXL_SPECIFIC	+= -include bits/intel_compatibility.h

endif

##################################################################

#### MCSTL OPTIONS ###############################################

ifeq ($(strip $(USE_MCSTL)),yes)

OPENMPFLAG	?= -fopenmp

ifeq (,$(strip $(wildcard $(strip $(MCSTL_ROOT))/c++/mcstl.h)))
$(error ERROR: could not find a MCSTL installation in MCSTL_ROOT=$(MCSTL_ROOT))
endif

MCSTL_CPPFLAGS		+= $(OPENMPFLAG) -D__MCSTL__ $(MCSTL_INCLUDES_PREPEND) -I$(MCSTL_ROOT)/c++
MCSTL_LDFLAGS		+= $(OPENMPFLAG)

MCSTL_INCLUDES_PREPEND	+= $(if $(findstring 4.3,$(COMPILER)),-I$(MCSTL_ROOT)/c++/mod_stl/gcc-4.3)

endif

##################################################################

#### BOOST OPTIONS ###############################################

BOOST_COMPILER_OPTIONS	 = \
	-DSTXXL_BOOST_TIMESTAMP \
	-DSTXXL_BOOST_CONFIG \
	-DSTXXL_BOOST_FILESYSTEM \
	-DSTXXL_BOOST_THREADS \
	-DSTXXL_BOOST_RANDOM \
	$(if $(strip $(BOOST_ROOT)),-I$(strip $(BOOST_ROOT)))

BOOST_LIB_COMPILER_SUFFIX	?=
BOOST_LIB_MT_SUFFIX		?= -mt
BOOST_LINKER_OPTIONS		 = \
	-lboost_thread$(BOOST_LIB_COMPILER_SUFFIX)$(BOOST_LIB_MT_SUFFIX) \
	-lboost_date_time$(BOOST_LIB_COMPILER_SUFFIX)$(BOOST_LIB_MT_SUFFIX) \
	-lboost_iostreams$(BOOST_LIB_COMPILER_SUFFIX)$(BOOST_LIB_MT_SUFFIX) \
	-lboost_filesystem$(BOOST_LIB_COMPILER_SUFFIX)$(BOOST_LIB_MT_SUFFIX)

##################################################################

#### CPPUNIT OPTIONS ############################################

CPPUNIT_COMPILER_OPTIONS	+=

CPPUNIT_LINKER_OPTIONS		+= -lcppunit -ldl

##################################################################

#### DEPENDENCIES ################################################

HEADER_FILES_BITS	+= namespace.h noncopyable.h version.h

HEADER_FILES_COMMON	+= aligned_alloc.h mutex.h rand.h semaphore.h state.h
HEADER_FILES_COMMON	+= timer.h utils.h gprof.h simple_vector.h
HEADER_FILES_COMMON	+= switch.h tmeta.h log.h exceptions.h debug.h tuple.h
HEADER_FILES_COMMON	+= types.h utils_ledasm.h settings.h seed.h

HEADER_FILES_IO		+= completion_handler.h io.h iobase.h iostats.h
HEADER_FILES_IO		+= mmap_file.h simdisk_file.h syscall_file.h
HEADER_FILES_IO		+= ufs_file.h wincall_file.h wfs_file.h boostfd_file.h

HEADER_FILES_MNG	+= adaptor.h async_schedule.h block_prefetcher.h
HEADER_FILES_MNG	+= buf_istream.h buf_ostream.h buf_writer.h mng.h
HEADER_FILES_MNG	+= write_pool.h prefetch_pool.h

HEADER_FILES_CONTAINERS	+= pager.h stack.h vector.h priority_queue.h queue.h
HEADER_FILES_CONTAINERS	+= map.h deque.h

HEADER_FILES_CONTAINERS_BTREE	+= btree.h iterator_map.h leaf.h node_cache.h
HEADER_FILES_CONTAINERS_BTREE	+= root_node.h node.h btree_pager.h iterator.h

HEADER_FILES_ALGO	+= adaptor.h inmemsort.h intksort.h run_cursor.h sort.h
HEADER_FILES_ALGO	+= async_schedule.h interleaved_alloc.h ksort.h
HEADER_FILES_ALGO	+= losertree.h scan.h stable_ksort.h random_shuffle.h

HEADER_FILES_STREAM	+= stream.h sort_stream.h

HEADER_FILES_UTILS	+= malloc.h

###################################################################

#### MISC #########################################################

DEPEXT	 = $(LIBNAME).d # extension of dependency files
OBJEXT	 = $(LIBNAME).o	# extension of object files
IIEXT	 = $(LIBNAME).ii
LIBEXT	 = a		# static library file extension
EXEEXT	 = $(LIBNAME).bin # executable file extension
RM	 = rm -f	# remove file command
LIBGEN	 = ar cr	# library generation
OUT	 = -o		# output file option for the compiler and linker

d	?= $(strip $(DEPEXT))
o	?= $(strip $(OBJEXT))
ii	?= $(strip $(IIEXT))
bin	?= $(strip $(EXEEXT))

###################################################################

#### COMPILE/LINK RULES ###########################################

DEPS_MAKEFILES	:= $(wildcard ../Makefile.subdir.gnu ../make.settings ../make.settings.local GNUmakefile Makefile.local)
%.$o: %.cpp $(DEPS_MAKEFILES)
	@$(RM) $@ $*.$d
	$(COMPILER) $(STXXL_COMPILER_OPTIONS) -MD -MF $*.$dT -c $(OUTPUT_OPTION) $< && mv $*.$dT $*.$d

%.$(ii): %.cpp $(DEPS_MAKEFILES)
	$(COMPILER) $(STXXL_COMPILER_OPTIONS) -E $(OUTPUT_OPTION) $<

LINK_STXXL	 = $(LINKER) $1 $(STXXL_LINKER_OPTIONS) -o $@

%.$(bin): %.$o $(STXXL_LIBDEPS)
	$(call LINK_STXXL, $<)

###################################################################

ifeq ($(strip $(USE_ICPC)),yes)
STXXL_CPPFLAGS_CXX	+= $(ICPC_CPPFLAGS)
STXXL_LDLIBS_CXX	+= $(ICPC_LDFLAGS)
endif

STXXL_COMPILER_OPTIONS	+= $(STXXL_CPPFLAGS_CXX)
STXXL_COMPILER_OPTIONS	+= $(STXXL_SPECIFIC)
STXXL_COMPILER_OPTIONS	+= $(OPT) $(DEBUG) $(WARNINGS)
STXXL_LINKER_OPTIONS	+= $(STXXL_LDLIBS_CXX)
STXXL_LINKER_OPTIONS	+= $(DEBUG)
STXXL_LINKER_OPTIONS	+= $(STXXL_LDFLAGS)
STXXL_LINKER_OPTIONS	+= $(STXXL_LDLIBS)

ifeq ($(strip $(USE_MCSTL)),yes)
STXXL_COMPILER_OPTIONS	+= $(MCSTL_CPPFLAGS)
STXXL_LINKER_OPTIONS	+= $(MCSTL_LDFLAGS)
endif

ifeq ($(strip $(USE_BOOST)),yes)
STXXL_COMPILER_OPTIONS	+= $(BOOST_COMPILER_OPTIONS)
STXXL_LINKER_OPTIONS	+= $(BOOST_LINKER_OPTIONS)
endif

STXXL_COMPILER_OPTIONS	+= $(CPPFLAGS)

# vim: syn=make

# This -*- Makefile -*- is intended for processing with GNU make.

TOPDIR	?= $(error TOPDIR not defined) # DO NOT CHANGE! This is set elsewhere.

# Change this file according to your paths.

# Instead of modifying this file, you could also set your modified variables
# in make.settings.local (needs to be created first).
-include $(TOPDIR)/make.settings.local

USE_BOOST	?= no	# set 'yes' to use Boost libraries or 'no' to not use Boost libraries
USE_LINUX	?= yes	# set 'yes' if you run Linux, 'no' otherwise
USE_MCSTL	?= no	# will be overriden from main Makefile
USE_ICPC	?= no	# will be overriden from main Makefile

STXXL_ROOT	?= $(HOME)/work/stxxl

ifeq ($(strip $(USE_ICPC)),yes)
COMPILER_ICPC	?= icpc
COMPILER	?= $(COMPILER_ICPC)
#ICPC_GCC	?= gcc-x.y    # override the gcc/g++ used to find headers and libraries
WARNINGS	?= -Wall -w1 -openmp-report0 -vec-report0
endif

ifeq ($(strip $(USE_MCSTL)),yes)
COMPILER_GCC	?= g++-4.2.3
LIBNAME		?= mcstxxl
# the root directory of your MCSTL installation
MCSTL_ROOT	?= $(HOME)/work/mcstl
endif

#BOOST_ROOT	?= /usr/local/boost-1.34.1

COMPILER_GCC	?= g++
COMPILER	?= $(COMPILER_GCC)
LINKER		?= $(COMPILER)
OPT		?= -O3 # compiler optimization level
WARNINGS	?= -W -Wall
DEBUG		?= # put here -g option to include the debug information into the binaries

LIBNAME		?= stxxl

#### TROUBLESHOOTING
#
# For automatical checking of order of the output elements in
# the sorters: stxxl::stream::sort, stxxl::stream::merge_runs,
# stxxl::sort, and stxxl::ksort use
#
#STXXL_SPECIFIC	+= -DSTXXL_CHECK_ORDER_IN_SORTS
#
# If your program aborts with message "read/write: wrong parameter"
# or "Invalid argument"
# this could be that your kernel does not support direct I/O
# then try to set it off recompiling the libs and your code with option
#
#STXXL_SPECIFIC	+= -DSTXXL_DIRECT_IO_OFF
#
# But for the best performance it is strongly recommended
# to reconfigure the kernel for the support of the direct I/O.
#
# FIXME: documentation needed
#
#STXXL_SPECIFIC += -DSTXXL_DEBUGMON

#### You usually shouldn't need to change the sections below #####

#### STXXL OPTIONS ###############################################

# check, whether stxxl has been configured
ifeq (,$(strip $(wildcard $(STXXL_ROOT)/include/stxxl.h)))
$(warning *** WARNING: STXXL has not been configured correctly)
ifeq (,$(strip $(wildcard $(CURDIR)/make.settings.local)))
ifneq (,$(strip $(wildcard $(CURDIR)/include/stxxl.h)))
$(warning *** WARNING: trying autoconfiguration for STXXL_ROOT=$(CURDIR:$(HOME)%=$$(HOME)%))
$(warning *** WARNING: you did not have a make.settings.local file -- creating ...)
$(shell echo 'STXXL_ROOT	 = $(CURDIR:$(HOME)%=$$(HOME)%)' >> $(CURDIR)/make.settings.local)
MCSTL_ROOT	?= $(HOME)/work/mcstl
$(shell echo '#MCSTL_ROOT	 = $(MCSTL_ROOT:$(HOME)%=$$(HOME)%)' >> $(CURDIR)/make.settings.local)
$(shell echo '#COMPILER_GCC	 = g++-4.2.3' >> $(CURDIR)/make.settings.local)
$(shell echo '#COMPILER_ICPC	 = icpc' >> $(CURDIR)/make.settings.local)
$(error ERROR: Please check make.settings.local and try again)
endif
else
$(warning *** WARNING: Please check make.settings.local)
endif
$(error ERROR: could not find a STXXL installation in STXXL_ROOT=$(STXXL_ROOT))
endif

# in the top dir, check whether STXXL_ROOT points to ourselves
ifneq (,$(wildcard make.settings))
stat1	 = $(shell stat -L -c '%d:%i' ./)
stat2	 = $(shell stat -L -c '%d:%i' $(STXXL_ROOT)/)

ifneq ($(stat1),$(stat2))
$(error ERROR: STXXL_ROOT=$(STXXL_ROOT) points to a different STXXL installation)
endif
endif

PTHREAD_FLAG	?= -pthread

STXXL_SPECIFIC	+= \
	$(PTHREAD_FLAG) \
	$(CPPFLAGS_ARCH) \
	-DSORT_OPTIMAL_PREFETCHING \
	-DUSE_MALLOC_LOCK \
	-DCOUNT_WAIT_TIME \
	-I$(strip $(STXXL_ROOT))/include \
	-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
	$(POSIX_MEMALIGN) $(XOPEN_SOURCE)

STXXL_LDFLAGS	+= $(PTHREAD_FLAG)
STXXL_LDLIBS	+= -L$(strip $(STXXL_ROOT))/lib -l$(LIBNAME)

STXXL_LIBDEPS	+= $(strip $(STXXL_ROOT))/lib/lib$(LIBNAME).$(LIBEXT)

UNAME_M		:= $(shell uname -m)
CPPFLAGS_ARCH	+= $(CPPFLAGS_$(UNAME_M))
CPPFLAGS_i686	?= -march=i686

##################################################################

#### ICPC OPTIONS ################################################

ifeq ($(strip $(USE_ICPC)),yes)

OPENMPFLAG	?= -openmp

ICPC_CPPFLAGS	+= $(if $(ICPC_GCC),-gcc-name=$(strip $(ICPC_GCC)))
ICPC_LDFLAGS	+= $(if $(ICPC_GCC),-gcc-name=$(strip $(ICPC_GCC)))

STXXL_SPECIFIC	+= -include bits/intel_compatibility.h

endif

##################################################################

#### MCSTL OPTIONS ###############################################

ifeq ($(strip $(USE_MCSTL)),yes)

OPENMPFLAG	?= -fopenmp

ifeq (,$(strip $(wildcard $(strip $(MCSTL_ROOT))/c++/mcstl.h)))
$(error ERROR: could not find a MCSTL installation in MCSTL_ROOT=$(MCSTL_ROOT))
endif

MCSTL_CPPFLAGS		+= $(OPENMPFLAG) -D__MCSTL__ $(MCSTL_INCLUDES_PREPEND) -I$(MCSTL_ROOT)/c++
MCSTL_LDFLAGS		+= $(OPENMPFLAG)

MCSTL_INCLUDES_PREPEND	+= $(if $(findstring 4.3,$(COMPILER)),-I$(MCSTL_ROOT)/c++/mod_stl/gcc-4.3)

endif

##################################################################

#### BOOST OPTIONS ###############################################

BOOST_COMPILER_OPTIONS	 = \
	-DSTXXL_BOOST_TIMESTAMP \
	-DSTXXL_BOOST_CONFIG \
	-DSTXXL_BOOST_FILESYSTEM \
	-DSTXXL_BOOST_THREADS \
	-DSTXXL_BOOST_RANDOM \
	$(if $(strip $(BOOST_ROOT)),-I$(strip $(BOOST_ROOT)))

BOOST_LIB_COMPILER_SUFFIX	?=
BOOST_LIB_MT_SUFFIX		?= -mt
BOOST_LINKER_OPTIONS		 = \
	-lboost_thread$(BOOST_LIB_COMPILER_SUFFIX)$(BOOST_LIB_MT_SUFFIX) \
	-lboost_date_time$(BOOST_LIB_COMPILER_SUFFIX)$(BOOST_LIB_MT_SUFFIX) \
	-lboost_iostreams$(BOOST_LIB_COMPILER_SUFFIX)$(BOOST_LIB_MT_SUFFIX) \
	-lboost_filesystem$(BOOST_LIB_COMPILER_SUFFIX)$(BOOST_LIB_MT_SUFFIX)

##################################################################

#### CPPUNIT OPTIONS ############################################

CPPUNIT_COMPILER_OPTIONS	+=

CPPUNIT_LINKER_OPTIONS		+= -lcppunit -ldl

##################################################################

#### DEPENDENCIES ################################################

HEADER_FILES_BITS	+= namespace.h noncopyable.h version.h

HEADER_FILES_COMMON	+= aligned_alloc.h mutex.h rand.h semaphore.h state.h
HEADER_FILES_COMMON	+= timer.h utils.h gprof.h simple_vector.h
HEADER_FILES_COMMON	+= switch.h tmeta.h log.h exceptions.h debug.h tuple.h
HEADER_FILES_COMMON	+= types.h utils_ledasm.h settings.h seed.h

HEADER_FILES_IO		+= completion_handler.h io.h iobase.h iostats.h
HEADER_FILES_IO		+= mmap_file.h simdisk_file.h syscall_file.h
HEADER_FILES_IO		+= ufs_file.h wincall_file.h wfs_file.h boostfd_file.h

HEADER_FILES_MNG	+= adaptor.h async_schedule.h block_prefetcher.h
HEADER_FILES_MNG	+= buf_istream.h buf_ostream.h buf_writer.h mng.h
HEADER_FILES_MNG	+= write_pool.h prefetch_pool.h

HEADER_FILES_CONTAINERS	+= pager.h stack.h vector.h priority_queue.h queue.h
HEADER_FILES_CONTAINERS	+= map.h deque.h

HEADER_FILES_CONTAINERS_BTREE	+= btree.h iterator_map.h leaf.h node_cache.h
HEADER_FILES_CONTAINERS_BTREE	+= root_node.h node.h btree_pager.h iterator.h

HEADER_FILES_ALGO	+= adaptor.h inmemsort.h intksort.h run_cursor.h sort.h
HEADER_FILES_ALGO	+= async_schedule.h interleaved_alloc.h ksort.h
HEADER_FILES_ALGO	+= losertree.h scan.h stable_ksort.h random_shuffle.h

HEADER_FILES_STREAM	+= stream.h sort_stream.h

HEADER_FILES_UTILS	+= malloc.h

###################################################################

#### MISC #########################################################

DEPEXT	 = $(LIBNAME).d # extension of dependency files
OBJEXT	 = $(LIBNAME).o	# extension of object files
LIBEXT	 = a		# static library file extension
EXEEXT	 = $(LIBNAME).bin # executable file extension
RM	 = rm -f	# remove file command
LIBGEN	 = ar cr	# library generation
OUT	 = -o		# output file option for the compiler and linker

d	?= $(strip $(DEPEXT))
o	?= $(strip $(OBJEXT))
bin	?= $(strip $(EXEEXT))

###################################################################

#### COMPILE/LINK RULES ###########################################

DEPS_MAKEFILES	:= $(wildcard ../Makefile.subdir.gnu ../make.settings ../make.settings.local GNUmakefile Makefile.local)
%.$o: %.cpp $(DEPS_MAKEFILES)
	@$(RM) $@ $*.$d
	$(COMPILER) $(STXXL_COMPILER_OPTIONS) -MD -MF $*.$dT -c $(OUTPUT_OPTION) $< && mv $*.$dT $*.$d

LINK_STXXL	 = $(LINKER) $1 $(STXXL_LINKER_OPTIONS) -o $@

%.$(bin): %.$o $(STXXL_LIBDEPS)
	$(call LINK_STXXL, $<)

###################################################################

ifeq ($(strip $(USE_ICPC)),yes)
STXXL_CPPFLAGS_CXX	+= $(ICPC_CPPFLAGS)
STXXL_LDLIBS_CXX	+= $(ICPC_LDFLAGS)
endif

STXXL_COMPILER_OPTIONS	+= $(STXXL_CPPFLAGS_CXX)
STXXL_COMPILER_OPTIONS	+= $(STXXL_SPECIFIC)
STXXL_COMPILER_OPTIONS	+= $(OPT) $(DEBUG) $(WARNINGS)
STXXL_LINKER_OPTIONS	+= $(STXXL_LDLIBS_CXX)
STXXL_LINKER_OPTIONS	+= $(DEBUG)
STXXL_LINKER_OPTIONS	+= $(STXXL_LDFLAGS)
STXXL_LINKER_OPTIONS	+= $(STXXL_LDLIBS)

ifeq ($(strip $(USE_MCSTL)),yes)
STXXL_COMPILER_OPTIONS	+= $(MCSTL_CPPFLAGS)
STXXL_LINKER_OPTIONS	+= $(MCSTL_LDFLAGS)
endif

ifeq ($(strip $(USE_BOOST)),yes)
STXXL_COMPILER_OPTIONS	+= $(BOOST_COMPILER_OPTIONS)
STXXL_LINKER_OPTIONS	+= $(BOOST_LINKER_OPTIONS)
endif

STXXL_COMPILER_OPTIONS	+= $(CPPFLAGS)

# vim: syn=make


plot has changed slightly with Ferret v6.07

git-svn-id: 0ef30dc7da0b07cedfa074587325a6c153c0ae55@10062 fdbf22ae-c210-0410-be80-ca943da6b8f8


fix parallel build race condition

fix parallel build race condition

git-svn-id: 4e7379b20b57f8e3dde5a0b7363f233184647162@516 4e380d45-d1fd-0310-85a7-d18ec86df0ad

# This -*- Makefile -*- is intended for processing with GNU make.
THISMAKEFILE	:= $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))

main: library

include make.settings

SUBDIRS	= algo common containers io lib mng stream utils

SUBDIRS-lib: $(SUBDIRS:%=lib-in-%)
SUBDIRS-tests: $(SUBDIRS:%=tests-in-%)
SUBDIRS-clean: $(SUBDIRS:%=clean-in-%)

# compute STXXL_CPPFLAGS/STXXL_LDLIBS for stxxl.mk
# don't include optimization, warning and debug flags
stxxl_mk_cppflags	 = $$(STXXL_CPPFLAGS_STXXL)
stxxl_mk_ldlibs		 = $$(STXXL_LDLIBS_STXXL)
ifeq ($(strip $(USE_MCSTL)),yes)
stxxl_mk_cppflags	+= $$(STXXL_CPPFLAGS_MCSTL)
stxxl_mk_ldlibs		+= $$(STXXL_LDLIBS_MCSTL)
endif
ifeq ($(strip $(USE_BOOST)),yes)
stxxl_mk_cppflags	+= $$(STXXL_CPPFLAGS_BOOST)
stxxl_mk_ldlibs		+= $$(STXXL_LDLIBS_BOOST)
endif

lib-in-lib:
	@# nothing to compile
lib-in-%:
	$(MAKE) -C $* lib

build-lib: SUBDIRS-lib
	$(MAKE) -C lib
	$(MAKE) -C utils create

$(LIBNAME).mk: build-lib
	$(RM) $@
	echo 'STXXL_CXX	 = $(COMPILER)'	>> $@
	echo 'STXXL_CPPFLAGS	 = $(stxxl_mk_cppflags)'	>> $@
	echo 'STXXL_LDLIBS	 = $(stxxl_mk_ldlibs)'	>> $@
	echo 'STXXL_CPPFLAGS_STXXL	 = $(STXXL_SPECIFIC)'	>> $@
	echo 'STXXL_LDLIBS_STXXL	 = $(STXXL_LDFLAGS) $(STXXL_LDLIBS)'	>> $@
	echo 'STXXL_LIBDEPS		 = $(STXXL_LIBDEPS)'	>> $@
	echo 'STXXL_CPPFLAGS_MCSTL	 = $(MCSTL_CPPFLAGS)'	>> $@
	echo 'STXXL_LDLIBS_MCSTL	 = $(MCSTL_LDFLAGS)'	>> $@
	echo 'STXXL_CPPFLAGS_BOOST	 = $(BOOST_COMPILER_OPTIONS)'	>> $@
	echo 'STXXL_LDLIBS_BOOST	 = $(BOOST_LINKER_OPTIONS)'	>> $@

library: $(LIBNAME).mk

lib/lib$(LIBNAME).$(LIBEXT): make.settings
	$(MAKE) -f $(THISMAKEFILE) library

ifneq (,$(wildcard .svn))
lib-in-common: common/version_svn.defs

ifeq (,$(strip $(shell svnversion . | tr -d 0-9)))
# clean checkout - use svn info
VERSION_DATE	:= $(shell LC_ALL=POSIX svn info . | sed -ne '/Last Changed Date/{s/.*: //;s/ .*//;s/-//gp}')
VERSION_SVN_REV	:= $(shell LC_ALL=POSIX svn info . | sed -ne '/Last Changed Rev/s/.*: //p')
else
# modified, mixed, ... checkout - use svnversion and today
VERSION_DATE	:= $(shell date "+%Y%m%d")
VERSION_SVN_REV	:= $(shell svnversion .)
endif

.PHONY: common/version_svn.defs
common/version_svn.defs:
	$(RM) $@.$(LIBNAME).tmp
	echo '#define STXXL_VERSION_STRING_DATE "$(VERSION_DATE)"' >> $@.$(LIBNAME).tmp
	echo '#define STXXL_VERSION_STRING_SVN_REVISION "$(VERSION_SVN_REV)"' >> $@.$(LIBNAME).tmp
	cmp -s $@ $@.$(LIBNAME).tmp || mv $@.$(LIBNAME).tmp $@
	$(RM) $@.$(LIBNAME).tmp
endif

VERSION		?= $(shell grep 'define *STXXL_VERSION_STRING_MA_MI_PL' common/version.cpp | cut -d'"' -f2)
PHASE		?= snapshot
DATE		?= $(shell date "+%Y%m%d")
REL_VERSION	:= $(VERSION)$(if $(strip $(DATE)),-$(DATE))
release:
	$(RM) -r reltmp stxxl-$(REL_VERSION).tar.gz stxxl-$(REL_VERSION).zip
	mkdir reltmp
	svn export . reltmp/stxxl-$(REL_VERSION)
	echo '#define STXXL_VERSION_STRING_PHASE "$(PHASE)"' > reltmp/stxxl-$(REL_VERSION)/common/version.defs
	$(if $(strip $(DATE)),echo '#define STXXL_VERSION_STRING_DATE "$(DATE)"' >> reltmp/stxxl-$(REL_VERSION)/common/version.defs)
	cd reltmp && tar cf - stxxl-$(REL_VERSION) | gzip -9 > ../stxxl-$(REL_VERSION).tar.gz && zip -r ../stxxl-$(REL_VERSION).zip stxxl-$(REL_VERSION)/*
	$(RM) -r reltmp
	@echo
	@echo "Your release has been created in stxxl-$(REL_VERSION).tar.gz and stxxl-$(REL_VERSION).zip"
	@echo "The following files are modified and not commited:"
	@svn status -q

tests-in-%: lib/lib$(LIBNAME).$(LIBEXT)
	$(MAKE) -C $* tests

tests: SUBDIRS-tests

clean-in-%:
	$(MAKE) -C $* clean

clean: SUBDIRS-clean
	$(RM) common/version_svn.defs
	$(RM) $(LIBNAME).mk

.PHONY: main library tests clean

# This -*- Makefile -*- is intended for processing with GNU make.
THISMAKEFILE	:= $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))

main: library

include make.settings

SUBDIRS	= algo common containers io lib mng stream utils

SUBDIRS-lib: $(SUBDIRS:%=lib-in-%)
SUBDIRS-tests: $(SUBDIRS:%=tests-in-%)
SUBDIRS-clean: $(SUBDIRS:%=clean-in-%)

# compute STXXL_CPPFLAGS/STXXL_LDLIBS for stxxl.mk
# don't include optimization, warning and debug flags
stxxl_mk_cppflags	 = $$(STXXL_CPPFLAGS_STXXL)
stxxl_mk_ldlibs		 = $$(STXXL_LDLIBS_STXXL)
ifeq ($(strip $(USE_MCSTL)),yes)
stxxl_mk_cppflags	+= $$(STXXL_CPPFLAGS_MCSTL)
stxxl_mk_ldlibs		+= $$(STXXL_LDLIBS_MCSTL)
endif
ifeq ($(strip $(USE_BOOST)),yes)
stxxl_mk_cppflags	+= $$(STXXL_CPPFLAGS_BOOST)
stxxl_mk_ldlibs		+= $$(STXXL_LDLIBS_BOOST)
endif

lib-in-lib:
	@# nothing to compile
lib-in-%:
	$(MAKE) -C $* lib

build-lib: SUBDIRS-lib
	$(MAKE) -C lib
	$(MAKE) -C utils create

$(LIBNAME).mk: build-lib
	$(RM) $@
	echo 'STXXL_CXX	 = $(COMPILER)'	>> $@
	echo 'STXXL_CPPFLAGS	 = $(stxxl_mk_cppflags)'	>> $@
	echo 'STXXL_LDLIBS	 = $(stxxl_mk_ldlibs)'	>> $@
	echo 'STXXL_CPPFLAGS_STXXL	 = $(STXXL_SPECIFIC)'	>> $@
	echo 'STXXL_LDLIBS_STXXL	 = $(STXXL_LDFLAGS) $(STXXL_LDLIBS)'	>> $@
	echo 'STXXL_LIBDEPS		 = $(STXXL_LIBDEPS)'	>> $@
	echo 'STXXL_CPPFLAGS_MCSTL	 = $(MCSTL_CPPFLAGS)'	>> $@
	echo 'STXXL_LDLIBS_MCSTL	 = $(MCSTL_LDFLAGS)'	>> $@
	echo 'STXXL_CPPFLAGS_BOOST	 = $(BOOST_COMPILER_OPTIONS)'	>> $@
	echo 'STXXL_LDLIBS_BOOST	 = $(BOOST_LINKER_OPTIONS)'	>> $@

library: $(LIBNAME).mk

lib/lib$(LIBNAME).$(LIBEXT): make.settings
	$(MAKE) -f $(THISMAKEFILE) library

ifneq (,$(wildcard .svn))
lib-in-common: common/version_svn.defs

ifeq (,$(strip $(shell svnversion . | tr -d 0-9)))
# clean checkout - use svn info
VERSION_DATE	:= $(shell LC_ALL=POSIX svn info . | sed -ne '/Last Changed Date/{s/.*: //;s/ .*//;s/-//gp}')
VERSION_SVN_REV	:= $(shell LC_ALL=POSIX svn info . | sed -ne '/Last Changed Rev/s/.*: //p')
else
# modified, mixed, ... checkout - use svnversion and today
VERSION_DATE	:= $(shell date "+%Y%m%d")
VERSION_SVN_REV	:= $(shell svnversion .)
endif

.PHONY: common/version_svn.defs
common/version_svn.defs:
	$(RM) $@.tmp
	echo '#define STXXL_VERSION_STRING_DATE "$(VERSION_DATE)"' >> $@.tmp
	echo '#define STXXL_VERSION_STRING_SVN_REVISION "$(VERSION_SVN_REV)"' >> $@.tmp
	cmp -s $@ $@.tmp || mv $@.tmp $@
	$(RM) $@.tmp
endif

VERSION		?= $(shell grep 'define *STXXL_VERSION_STRING_MA_MI_PL' common/version.cpp | cut -d'"' -f2)
PHASE		?= snapshot
DATE		?= $(shell date "+%Y%m%d")
REL_VERSION	:= $(VERSION)$(if $(strip $(DATE)),-$(DATE))
release:
	$(RM) -r reltmp stxxl-$(REL_VERSION).tar.gz stxxl-$(REL_VERSION).zip
	mkdir reltmp
	svn export . reltmp/stxxl-$(REL_VERSION)
	echo '#define STXXL_VERSION_STRING_PHASE "$(PHASE)"' > reltmp/stxxl-$(REL_VERSION)/common/version.defs
	$(if $(strip $(DATE)),echo '#define STXXL_VERSION_STRING_DATE "$(DATE)"' >> reltmp/stxxl-$(REL_VERSION)/common/version.defs)
	cd reltmp && tar cf - stxxl-$(REL_VERSION) | gzip -9 > ../stxxl-$(REL_VERSION).tar.gz && zip -r ../stxxl-$(REL_VERSION).zip stxxl-$(REL_VERSION)/*
	$(RM) -r reltmp
	@echo
	@echo "Your release has been created in stxxl-$(REL_VERSION).tar.gz and stxxl-$(REL_VERSION).zip"
	@echo "The following files are modified and not commited:"
	@svn status -q

tests-in-%: lib/lib$(LIBNAME).$(LIBEXT)
	$(MAKE) -C $* tests

tests: SUBDIRS-tests

clean-in-%:
	$(MAKE) -C $* clean

clean: SUBDIRS-clean
	$(RM) common/version_svn.defs
	$(RM) $(LIBNAME).mk

.PHONY: main library tests clean


don't forget to export STXXL_LDFLAGS to stxxl.mk

git-svn-id: 4e7379b20b57f8e3dde5a0b7363f233184647162@503 4e380d45-d1fd-0310-85a7-d18ec86df0ad

# This -*- Makefile -*- is intended for processing with GNU make.
THISMAKEFILE	:= $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))

main: library

include make.settings

SUBDIRS	= algo common containers io lib mng stream utils

SUBDIRS-lib: $(SUBDIRS:%=lib-in-%)
SUBDIRS-tests: $(SUBDIRS:%=tests-in-%)
SUBDIRS-clean: $(SUBDIRS:%=clean-in-%)

# compute STXXL_CPPFLAGS/STXXL_LDLIBS for stxxl.mk
# don't include optimization, warning and debug flags
stxxl_mk_cppflags	 = $$(STXXL_CPPFLAGS_STXXL)
stxxl_mk_ldlibs		 = $$(STXXL_LDLIBS_STXXL)
ifeq ($(strip $(USE_MCSTL)),yes)
stxxl_mk_cppflags	+= $$(STXXL_CPPFLAGS_MCSTL)
stxxl_mk_ldlibs		+= $$(STXXL_LDLIBS_MCSTL)
endif
ifeq ($(strip $(USE_BOOST)),yes)
stxxl_mk_cppflags	+= $$(STXXL_CPPFLAGS_BOOST)
stxxl_mk_ldlibs		+= $$(STXXL_LDLIBS_BOOST)
endif

lib-in-lib:
	@# nothing to compile
lib-in-%:
	$(MAKE) -C $* lib

build-lib: SUBDIRS-lib
	$(MAKE) -C lib
	$(MAKE) -C utils create

$(LIBNAME).mk: build-lib
	echo 'STXXL_CXX	 = $(COMPILER)'	> $@
	echo 'STXXL_CPPFLAGS	 = $(stxxl_mk_cppflags)'	>> $@
	echo 'STXXL_LDLIBS	 = $(stxxl_mk_ldlibs)'	>> $@
	echo 'STXXL_CPPFLAGS_STXXL	 = $(STXXL_SPECIFIC)'	>> $@
	echo 'STXXL_LDLIBS_STXXL	 = $(STXXL_LDFLAGS) $(STXXL_LDLIBS)'	>> $@
	echo 'STXXL_LIBDEPS		 = $(STXXL_LIBDEPS)'	>> $@
	echo 'STXXL_CPPFLAGS_MCSTL	 = $(MCSTL_CPPFLAGS)'	>> $@
	echo 'STXXL_LDLIBS_MCSTL	 = $(MCSTL_LDFLAGS)'	>> $@
	echo 'STXXL_CPPFLAGS_BOOST	 = $(BOOST_COMPILER_OPTIONS)'	>> $@
	echo 'STXXL_LDLIBS_BOOST	 = $(BOOST_LINKER_OPTIONS)'	>> $@

library: $(LIBNAME).mk

lib/lib$(LIBNAME).$(LIBEXT): make.settings
	$(MAKE) -f $(THISMAKEFILE) library

ifneq (,$(wildcard .svn))
lib-in-common: common/version_svn.defs

ifeq (,$(strip $(shell svnversion . | tr -d 0-9)))
# clean checkout - use svn info
VERSION_DATE	:= $(shell LC_ALL=POSIX svn info . | sed -ne '/Last Changed Date/{s/.*: //;s/ .*//;s/-//gp}')
VERSION_SVN_REV	:= $(shell LC_ALL=POSIX svn info . | sed -ne '/Last Changed Rev/s/.*: //p')
else
# modified, mixed, ... checkout - use svnversion and today
VERSION_DATE	:= $(shell date "+%Y%m%d")
VERSION_SVN_REV	:= $(shell svnversion .)
endif

.PHONY: common/version_svn.defs
common/version_svn.defs:
	echo '#define STXXL_VERSION_STRING_DATE "$(VERSION_DATE)"' > $@.tmp
	echo '#define STXXL_VERSION_STRING_SVN_REVISION "$(VERSION_SVN_REV)"' >> $@.tmp
	cmp -s $@ $@.tmp || mv $@.tmp $@
	$(RM) $@.tmp
endif

VERSION		?= $(shell grep 'define *STXXL_VERSION_STRING_MA_MI_PL' common/version.cpp | cut -d'"' -f2)
PHASE		?= snapshot
DATE		?= $(shell date "+%Y%m%d")
REL_VERSION	:= $(VERSION)$(if $(strip $(DATE)),-$(DATE))
release:
	$(RM) -r reltmp stxxl-$(REL_VERSION).tar.gz stxxl-$(REL_VERSION).zip
	mkdir reltmp
	svn export . reltmp/stxxl-$(REL_VERSION)
	echo '#define STXXL_VERSION_STRING_PHASE "$(PHASE)"' > reltmp/stxxl-$(REL_VERSION)/common/version.defs
	$(if $(strip $(DATE)),echo '#define STXXL_VERSION_STRING_DATE "$(DATE)"' >> reltmp/stxxl-$(REL_VERSION)/common/version.defs)
	cd reltmp && tar cf - stxxl-$(REL_VERSION) | gzip -9 > ../stxxl-$(REL_VERSION).tar.gz && zip -r ../stxxl-$(REL_VERSION).zip stxxl-$(REL_VERSION)/*
	$(RM) -r reltmp
	@echo
	@echo "Your release has been created in stxxl-$(REL_VERSION).tar.gz and stxxl-$(REL_VERSION).zip"
	@echo "The following files are modified and not commited:"
	@svn status -q

tests-in-%: lib/lib$(LIBNAME).$(LIBEXT)
	$(MAKE) -C $* tests

tests: SUBDIRS-tests

clean-in-%:
	$(MAKE) -C $* clean

clean: SUBDIRS-clean
	$(RM) common/version_svn.defs
	$(RM) $(LIBNAME).mk

.PHONY: main library tests clean

# This -*- Makefile -*- is intended for processing with GNU make.
THISMAKEFILE	:= $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))

main: library

include make.settings

SUBDIRS	= algo common containers io lib mng stream utils

SUBDIRS-lib: $(SUBDIRS:%=lib-in-%)
SUBDIRS-tests: $(SUBDIRS:%=tests-in-%)
SUBDIRS-clean: $(SUBDIRS:%=clean-in-%)

# compute STXXL_CPPFLAGS/STXXL_LDLIBS for stxxl.mk
# don't include optimization, warning and debug flags
stxxl_mk_cppflags	 = $$(STXXL_CPPFLAGS_STXXL)
stxxl_mk_ldlibs		 = $$(STXXL_LDLIBS_STXXL)
ifeq ($(strip $(USE_MCSTL)),yes)
stxxl_mk_cppflags	+= $$(STXXL_CPPFLAGS_MCSTL)
stxxl_mk_ldlibs		+= $$(STXXL_LDLIBS_MCSTL)
endif
ifeq ($(strip $(USE_BOOST)),yes)
stxxl_mk_cppflags	+= $$(STXXL_CPPFLAGS_BOOST)
stxxl_mk_ldlibs		+= $$(STXXL_LDLIBS_BOOST)
endif

lib-in-lib:
	@# nothing to compile
lib-in-%:
	$(MAKE) -C $* lib

build-lib: SUBDIRS-lib
	$(MAKE) -C lib
	$(MAKE) -C utils create

$(LIBNAME).mk: build-lib
	echo 'STXXL_CXX	 = $(COMPILER)'	> $@
	echo 'STXXL_CPPFLAGS	 = $(stxxl_mk_cppflags)'	>> $@
	echo 'STXXL_LDLIBS	 = $(stxxl_mk_ldlibs)'	>> $@
	echo 'STXXL_CPPFLAGS_STXXL	 = $(STXXL_SPECIFIC)'	>> $@
	echo 'STXXL_LDLIBS_STXXL	 = $(STXXL_LDLIBS)'	>> $@
	echo 'STXXL_LIBDEPS		 = $(STXXL_LIBDEPS)'	>> $@
	echo 'STXXL_CPPFLAGS_MCSTL	 = $(MCSTL_CPPFLAGS)'	>> $@
	echo 'STXXL_LDLIBS_MCSTL	 = $(MCSTL_LDFLAGS)'	>> $@
	echo 'STXXL_CPPFLAGS_BOOST	 = $(BOOST_COMPILER_OPTIONS)'	>> $@
	echo 'STXXL_LDLIBS_BOOST	 = $(BOOST_LINKER_OPTIONS)'	>> $@

library: $(LIBNAME).mk

lib/lib$(LIBNAME).$(LIBEXT): make.settings
	$(MAKE) -f $(THISMAKEFILE) library

ifneq (,$(wildcard .svn))
lib-in-common: common/version_svn.defs

ifeq (,$(strip $(shell svnversion . | tr -d 0-9)))
# clean checkout - use svn info
VERSION_DATE	:= $(shell LC_ALL=POSIX svn info . | sed -ne '/Last Changed Date/{s/.*: //;s/ .*//;s/-//gp}')
VERSION_SVN_REV	:= $(shell LC_ALL=POSIX svn info . | sed -ne '/Last Changed Rev/s/.*: //p')
else
# modified, mixed, ... checkout - use svnversion and today
VERSION_DATE	:= $(shell date "+%Y%m%d")
VERSION_SVN_REV	:= $(shell svnversion .)
endif

.PHONY: common/version_svn.defs
common/version_svn.defs:
	echo '#define STXXL_VERSION_STRING_DATE "$(VERSION_DATE)"' > $@.tmp
	echo '#define STXXL_VERSION_STRING_SVN_REVISION "$(VERSION_SVN_REV)"' >> $@.tmp
	cmp -s $@ $@.tmp || mv $@.tmp $@
	$(RM) $@.tmp
endif

VERSION		?= $(shell grep 'define *STXXL_VERSION_STRING_MA_MI_PL' common/version.cpp | cut -d'"' -f2)
PHASE		?= snapshot
DATE		?= $(shell date "+%Y%m%d")
REL_VERSION	:= $(VERSION)$(if $(strip $(DATE)),-$(DATE))
release:
	$(RM) -r reltmp stxxl-$(REL_VERSION).tar.gz stxxl-$(REL_VERSION).zip
	mkdir reltmp
	svn export . reltmp/stxxl-$(REL_VERSION)
	echo '#define STXXL_VERSION_STRING_PHASE "$(PHASE)"' > reltmp/stxxl-$(REL_VERSION)/common/version.defs
	$(if $(strip $(DATE)),echo '#define STXXL_VERSION_STRING_DATE "$(DATE)"' >> reltmp/stxxl-$(REL_VERSION)/common/version.defs)
	cd reltmp && tar cf - stxxl-$(REL_VERSION) | gzip -9 > ../stxxl-$(REL_VERSION).tar.gz && zip -r ../stxxl-$(REL_VERSION).zip stxxl-$(REL_VERSION)/*
	$(RM) -r reltmp
	@echo
	@echo "Your release has been created in stxxl-$(REL_VERSION).tar.gz and stxxl-$(REL_VERSION).zip"
	@echo "The following files are modified and not commited:"
	@svn status -q

tests-in-%: lib/lib$(LIBNAME).$(LIBEXT)
	$(MAKE) -C $* tests

tests: SUBDIRS-tests

clean-in-%:
	$(MAKE) -C $* clean

clean: SUBDIRS-clean
	$(RM) common/version_svn.defs
	$(RM) $(LIBNAME).mk

.PHONY: main library tests clean