text: create or replace function content_folder__del (integer, boolean)
  returns integer as '
  declare
    delete__folder_id              alias for $1;  
    p_cascade_p                    alias for $2; -- default ''f''
    v_count                        integer;       
    v_child_row                    record;
    v_parent_id                    integer;  
    v_path                         varchar;     
    v_folder_sortkey               varbit;
  begin
  
    if p_cascade_p = ''f'' then
      select count(*) into v_count from cr_items 
       where parent_id = delete__folder_id;
      -- check if the folder contains any items
      if v_count > 0 then
        v_path := content_item__get_path(delete__folder_id, null);
        raise EXCEPTION ''-20000: Folder ID % (%) cannot be deleted because it is not empty.'', delete__folder_id, v_path;
      end if;  
    else 
    -- delete children
      select into v_folder_sortkey tree_sortkey
      from cr_items where item_id=delete__folder_id;
  
      for v_child_row in select
          item_id, tree_sortkey, name
          from cr_items
          where tree_sortkey between v_folder_sortkey and tree_right(v_folder_sortkey)   
  	and tree_sortkey != v_folder_sortkey
          order by tree_sortkey desc
      loop
  	if content_folder__is_folder(v_child_row.item_id) then
  	  perform content_folder__delete(v_child_row.item_id);
          else
           perform content_item__delete(v_child_row.item_id);
  	end if;
      end loop;
    end if;
  
    PERFORM content_folder__unregister_content_type(
        delete__folder_id,
        ''content_revision'',
        ''t'' 
    );
  
    delete from cr_folder_type_map
      where folder_id = delete__folder_id;
  
    select parent_id into v_parent_id from cr_items 
      where item_id = delete__folder_id;
    raise notice ''deleteing folder %'',delete__folder_id;
    PERFORM content_item__delete(delete__folder_id);
  
    -- check if any folders are left in the parent
    update cr_folders set has_child_folders = ''f'' 
      where folder_id = v_parent_id and not exists (
        select 1 from cr_items 
          where parent_id = v_parent_id and content_type = ''content_folder'');
  
    return 0; 
  end;' language 'plpgsql';
  
  create or replace function content_folder__delete (integer, boolean)
  returns integer as '
  declare
    delete__folder_id              alias for $1;  
    p_cascade_p                    alias for $2;  -- default ''f''
  begin
          PERFORM content_folder__del(delete__folder_id,p_cascade_p);
    return 0; 
  end;' language 'plpgsql';
  
  select define_function_args('content_folder__move','folder_id,target_folder_id,name;null');
  
  create or replace function content_folder__move (integer,integer,varchar)
  returns integer as '
  declare
    move__folder_id              alias for $1;  
    move__target_folder_id       alias for $2;
    move__name                   alias for $3; -- default null
    v_source_folder_id           integer;       
    v_valid_folders_p            integer;
  begin
  
    select 
      count(*)
    into 
      v_valid_folders_p
    from 
      cr_folders
    where
      folder_id = move__target_folder_id
    or 
      folder_id = move__folder_id;
  
    if v_valid_folders_p != 2 then
      raise EXCEPTION ''-20000: content_folder.move - Not valid folder(s)'';
    end if;
  
    if move__folder_id = content_item__get_root_folder(null) or
      move__folder_id = content_template__get_root_folder() then
      raise EXCEPTION ''-20000: content_folder.move - Cannot move root folder'';
    end if;
    
    if move__target_folder_id = move__folder_id then
      raise EXCEPTION ''-20000: content_folder.move - Cannot move a folder to itself'';
    end if;
  
    if content_folder__is_sub_folder(move__folder_id, move__target_folder_id) = ''t'' then
      raise EXCEPTION ''-20000: content_folder.move - Destination folder is subfolder'';
    end if;
  
    if content_folder__is_registered(move__target_folder_id,''content_folder'',''f'') != ''t'' then
      raise EXCEPTION ''-20000: content_folder.move - Destination folder does not allow subfolders'';
    end if;
  
    select parent_id into v_source_folder_id from cr_items 
      where item_id = move__folder_id;
  
     -- update the parent_id for the folder
     update cr_items 
       set parent_id = move__target_folder_id,
           name = coalesce ( move__name, name )
       where item_id = move__folder_id;
  
    -- update the has_child_folders flags
  
    -- update the source
    update cr_folders set has_child_folders = ''f'' 
      where folder_id = v_source_folder_id and not exists (
        select 1 from cr_items 
          where parent_id = v_source_folder_id 
            and content_type = ''content_folder'');
  
    -- update the destination
    update cr_folders set has_child_folders = ''t''
      where folder_id = move__target_folder_id;
  
    return 0; 
  end;' language 'plpgsql';
  
  select define_function_args('content_type__unregister_relation_type','content_type,target_type,relation_tag;null');
  
  -- make it same as in oracle
  select define_function_args('content_type__rotate_template','template_id,v_content_type,use_context');
  