Rachel Rogers
Rachel Rogers

Reputation: 41

MySQL Inheritance via 1 Table - Permissions

I have a table in our MySQL database called "folder". It stores the names of virtual folders for different users in our website. Structure below:

CREATE TABLE IF NOT EXISTS `folder` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userId` int(11) NOT NULL,
  `parentId` int(11) DEFAULT NULL,
  `folderName` varchar(255) NOT NULL,
  `isPublic` int(1) NOT NULL DEFAULT '0'
  PRIMARY KEY (`id`)
);

The website allows for any number of child folders within folders, so:

Base Folder
- Child Folder 1
--- Child Folder 2
etc

Each folder can have a public or private status. So:

Base Folder (Public)
- Child Folder 1 (Private)
--- Child Folder 2 (Private)

If "Child Folder 1" is set to "Private" it will always cause sub-folders to be private, no matter if they've been set as public in the dd.

My question is, how can I decide whether a specific folder is public or private via MySQL, considering the inheritance?

Take "Child Folder 2" as an example. To check if that is private or public we can do this:

SELECT isPublic FROM folder WHERE folderName = "Child Folder 2";

(just an example, in the code we use the folder ids :))

This doesn't account for inheritance though. So the parent folder may be set as private.

Any idea how I can loop through any number of parent folders until a private state is found or there's no more parent folders. Ideally I need to end up with a 1 or a 0 returned from the query, 1 being public and 0 private.

Thanks in advance, Red.

Upvotes: 1

Views: 152

Answers (3)

Rachel Rogers
Rachel Rogers

Reputation: 41

I figured it out with some help from here - How to do the Recursive SELECT query in MySQL?

select MIN(IF(isPublic>0, 1, 0)), @pv := if(isPublic>0,parentId,0) as 'parentId' 
from (select * from folder order by id desc) t
join (select @pv := 270) tmp
where id = @pv

The result is a 1 for public or 0 for private. I used IF(isPublic>0, 1, 0) above as isPublic can actually be a 1 or 2 in my code.

Upvotes: 1

Dobromir Velev
Dobromir Velev

Reputation: 528

Here is a simple stored procedure that can do this in MySQL. It has two arguments testid for the id of the folder and param1 which will store the result

DELIMITER //
CREATE PROCEDURE test_public(IN testid INT,OUT param1 INT)
BEGIN
DECLARE parent,public INT DEFAULT -1;

WHILE testid!=0 DO
SELECT f.parentID,f.isPublic INTO parent,public FROM folder f WHERE f.id = testid ;
IF (parent is not NULL and public is not NULL and parent!=0 and public!=0) THEN
  set testid=parent;
ELSE
  set testid=0;
END  IF;
END WHILE;

select public into param1;
END//
delimiter ;

/* Usage - @a will be 1 if the folder is public, 0 if it is private */
call test_public(3,@a);
select @a;

Upvotes: 1

Pawan Kumar Sharma
Pawan Kumar Sharma

Reputation: 221

set folder name for that you wanna to get check that

check_public($folder_name);
function check_public($folder_name, $parent_id = FALSE) {
    $query = "select * from folder where ";
    echo $query.=$parent_id ? ("id =" . $parent_id) : ("folderName ='" . $folder_name . "'");exit;
    $result = mysql_query($query);
    if (mysql_num_rows($result)) {
        $row = mysql_fetch_object($result);
        if ($row->isPublic && $row->parentId) {
            check_public($folder_name, $row->parentId);
        } else {
            $public = $row->isPublic ? "public" : "private";
            echo $folder_name . ' is ' . $public;
            exit;
        }
    } else {
        echo 'folder name is not amtched in database';
    }
}

Upvotes: 0

Related Questions