-- subtree division metadata functions
DROP FUNCTION IF EXISTS sp_recalculate_tree_metadata(tablename varchar,field_id varchar,field_parentid varchar,field_level varchar,field_ordering varchar,field_div_l varchar,field_div_r varchar);
DROP FUNCTION IF EXISTS _sp_recalc_meta_recursive(tablename varchar,field_id varchar,field_parentid varchar,field_level varchar,field_ordering varchar,field_div_l varchar,field_div_r varchar, root integer, left integer );

CREATE or REPLACE FUNCTION _sp_recalc_meta_recursive(
	tablename varchar,
	field_id varchar,
	field_parentid varchar,
	field_level varchar,
	field_ordering varchar,
	field_div_l varchar,
	field_div_r varchar,
	root integer,
	left integer ) returns integer as $$
DECLARE
	right integer;
	query varchar;
	recset refcursor;
	recset2 refcursor;
	rec record;
	rec2 record;
	retleft integer;
BEGIN
	retleft:=left;
	-- FIXME: lehetne itt egyetlen okos update where field_div_l is null-al es akkor nincs szukseg cursorra jelen esetben
	-- getting current left value
	if root is not null then
		query:='select '||field_div_l||' as div_l from '||tablename||' where '||field_id||'='||root||' order by '||field_ordering;
	else
		query:='select '||field_div_l||' as div_l from '||tablename||' where '||field_id||' is null order by '||field_ordering;
	end if;

	open recset for execute query;
	fetch recset into rec;
	close recset;
	-- if is null then set it to left
	if rec.div_l is null then
		if root is not null then
			query:='update '||tablename||' set '||field_div_l||'='||retleft||' where '||field_id||'='||root;
		else
			query:='update '||tablename||' set '||field_div_l||'='||retleft||' where '||field_id||' is null';
		end if;
		execute query;
	end if;
	-- on childs
	if root is not null then
		query:='select '||field_id||' as id from '||tablename||' where '||field_parentid||'='||root||' order by '||field_ordering;
	else
		query:='select '||field_id||' as id from '||tablename||' where '||field_parentid||' is null order by '||field_ordering;
	end if;
	for rec in execute query loop
		query:='select _sp_recalc_meta_recursive('''||tablename||''','''||field_id||''','''||field_parentid||''','''||field_level||''','''||field_ordering||''','''||field_div_l||''','''||field_div_r||''','||rec.id||','||retleft+1||') as num';
		open recset2 for execute query;
		fetch recset2 into rec2;
		close recset2;
		retleft:=rec2.num;
	end loop;
	if root is not null then
		query:='update '||tablename||' set '||field_div_r||'='||retleft+1||' where '||field_id||'='||root;
	else
		query:='update '||tablename||' set '||field_div_r||'='||retleft+1||' where '||field_id||' is null';
	end if;
	execute query;
	RETURN retleft+1;
END;
$$ language plpgsql;

comment on function _sp_recalc_meta_recursive(tablename varchar,field_id varchar,field_parentid varchar,field_level varchar,field_ordering varchar,field_div_l varchar,field_div_r varchar, root integer, left integer )
	is 'function for calculating subtree metadata - recursive internal';

CREATE or REPLACE FUNCTION sp_recalculate_tree_metadata(
	tablename varchar,
	field_id varchar,
	field_parentid varchar,
	field_level varchar,
	field_ordering varchar,
	field_div_l varchar,
	field_div_r varchar ) returns varchar as $$
DECLARE
	query varchar;
BEGIN
	query:='update '||tablename||' set '||field_div_l||'=null,'||field_div_r||'=null';
	execute query;

	query:='select _sp_recalc_meta_recursive('''||tablename||''','''||field_id||''','''||field_parentid||''','''||field_level||''','''||field_ordering||''','''||field_div_l||''','''||field_div_r||''',null,1)';
	execute query;
	RETURN 'done';
END;
$$ language plpgsql;

comment on function sp_recalculate_tree_metadata(tablename varchar,field_id varchar,field_parentid varchar,field_level varchar,field_ordering varchar,field_div_l varchar,field_div_r varchar)
	is 'function calculating metadata: params(table,id,parentid,level,ordering,div_l,div_r)';


