I’m a newbie to sql and am trying to follow this example here:
http://net.tutsplus.com/tutorials/php/a-better-login-system/
So gist of the problem is,
- There are
permissionsthat allow access to resources - There are
rolesthat can have multiplepermissions - There are
usersthat may have multiplerolesand multiplepermissions
The db tables are listed as follows:
permission role user role_permissions user_roles and user_permissions
And here is the code to create the tables:
CREATE TABLE "permission" (
"id" SERIAL PRIMARY KEY,
"permission_key" VARCHAR(32) NOT NULL UNIQUE,
"permission_name" VARCHAR(32) NOT NULL);
CREATE TABLE "role" (
"id" SERIAL PRIMARY KEY,
"role_name" varchar(32) NOT NULL);
CREATE TABLE "role_permissions" (
"id" SERIAL PRIMARY KEY,
"role_id" INTEGER NOT NULL,
"permission_id" INTEGER NOT NULL,
"value" BOOLEAN NOT NULL DEFAULT FALSE,
"created_date" DATE NOT NULL,
UNIQUE ("role_id","permission_id"));
CREATE TABLE "user" (
"id" SERIAL PRIMARY KEY,
"username" VARCHAR(32) UNIQUE);
CREATE TABLE "user_permissions" (
"id" SERIAL PRIMARY KEY,
"user_id" INTEGER NOT NULL,
"permission_id" INTEGER NOT NULL,
"value" BOOLEAN NOT NULL DEFAULT FALSE,
"created_date" DATE NOT NULL,
UNIQUE ("user_id","permission_id"));
CREATE TABLE "user_roles" (
"id" SERIAL PRIMARY KEY,
"user_id" INTEGER NOT NULL,
"role_id" INTEGER NOT NULL,
"created_date" DATE NOT NULL,
UNIQUE ("user_id", "role_id"));
My question is:
I want to be able to write the following in an sql statement:
-
“Find me all
PERMISSIONSthat are available for aROLEwhoseNAMEis________“ -
“Find me all
PERMISSIONSthat are available for aUSERwhoseNAMEis________“
I know that I can use IDs to match everything, but I want to use names instead because it just makes more sense for me to think “find me all the permissions for user x”
Also, with the second question, please note that a user can get permissions via 2 ways:
User > Role > Permission
User > Permission
I would prefer to get the results in a single statement for brevity.
Also, if anyone knows how to translate that to a Korma query, I would be ever so grateful.
I had to make some choices. if there are both a user and a role permission, the user permission is applicable. I replaced the user and role by zuser and zrole, because they are reserved words in postgres, and I don’t like quoting. The query is not very easthetic in its current form but it seems to work. The data is fictuous.
Result:
BTW: the above query is still not correct. If a user belongs to more than one role, the query would produce multiple rows for that user. There needs to be added distinct/max() to the role subquery.
UPDATE: to solve the duplicate roles per person problems, I created this double nested CTE:
Its functioning can be shown by adding / uncommenting the data row
,(5,2,4, '2010-01-01' )to the user_role table. Again, I had to make a choice: if two roles exist for a user, with conflicting truth-values, theTrueone wins. I think the query can be simplified / beautified, but at least it works correctly now.