session.AdminPrivStruct = structnew();
You are creating a new structure on each iteration, overwriting any previous results each time. The end result is only one key. You need to initialize the structure before the loop.
<cfoutput query="GetAdminPriv"> <cfscript> session.AdminPrivStruct = structnew(); session.AdminPrivStruct["#SCREEN_Code#"] = SCREEN_code; session.AdminPrivStruct["#SCREEN_code#_Priv"] = APP_PRIVILEGES; </cfscript> #SCREEN_code# </cfoutput>
You have the session.AdminPrivStruct = structnew(); line inside the <cfoutput query=""> loop. That means each and very iteration through the loop will RESET session.AdminPrivstruct to a new, empty structure.
<cfscript> session.AdminPrivStruct = structnew(); </cfscript> <cfoutput query="GetAdminPriv"> <cfscript> session.AdminPrivStruct["#SCREEN_Code#"] = SCREEN_code; session.AdminPrivStruct["#SCREEN_code#_Priv"] = APP_PRIVILEGES; </cfscript> #SCREEN_code# </cfoutput>
Or maybe even just this.
<cfset session.AdminPrivQry = getAdminPriv>
Depends on if you really need a structure or just the record set data in a persistant scope.
You can, of course, put (almost) any sort of struct into the Session.
The technique that I use is that the session is always set-up in the menu screen of the application (because I know that this will in all cases reliably convey the session-cookie to the client). And I always have: <cfset Session.exists = "Y">.
The other screens, then, do (within a <cflock>): <cfset SessionExists = StructKeyExists(Session, "exists")>. Then, outside of the lock, we test SessionExists, and if it is not True, <cflocation> to the menu screen.
The session-initialization logic in the menu-screen uses the same technique to check for the existence of a session. If the session-data needs to contain a structure, it's initialized (with StructNew()) at that time. (Not that you have to do that, but I do.)
How will i check for the key values of the struct? Please provide sample...I am getting error from this statement [ <cfif structkeyexists(session.AdminPrivStruct["Admin"],"Admin")>yes<cfelse>no</cfif>] ....
Unless AdminPrivStruct contains an element named "Admin" which is itself a structure ... and you are asking CF to see if that structure contains an element which is named "Admin" ... then what you wanted to say is simply:
<cfif StructKeyExists(Session, "AdminPrivStruct") >
This is asking: "Does the struct named Session ... which, by the way, you know does exist ... contain an element named 'AdminPrivStruct' ?"
You then might wish to use StructKeyExists a second time to see if that structure-element contains the key, "Admin." Only then is it safe to test its value.
Lets say, I need to get the value of Admin and Admin_Priv which is within session.AdminPrivStruct... How would I do that?
Do I really need to spoon-feed this?
Let's think about it together.
- Session is a predefined structure: you know it exists. Okay then, no need to check for that.
- The next thing you need to know is whether or not Session contains a key named AdminPrivStruct... no matter what kind of value you think it's supposed to be. So you test for StructKeyExists(Session, "AdminPrivStruct") and somehow bail-out gracefully if it's not there. (For instance, the session may have expired. More on that below.)
- Having established that Session.AdminPrivStruct (or if you prefer, Session["AdminPrivStruct"]) does in fact exist, you can now test to see if that variable ... which we shall merely presume is a structure too ... contains a key named "Admin", viz: StructKeyExists(Session.AdminPrivStruct, "Admin"). And so on.
You can, if you try, see your way clear to do this without help from the community... and, you need to master this. We're here to "teach you to fish..."
Now for a few practical comments...
- "All that defensive coding" can quickly become tedious, and it's overhead that is wasted most of the time. It represents what we call a "pessimistic" approach... walking into the field assuming that it is a mine-field and testing every step. (Good way to cross a field, but it just takes twice as long.) Another approach is to wrap the block in a <cftry> block, and then, "just do it." Probably nothing will go wrong, but if something does go wrong you can <cfcatch> the exception and deal with it ... basically by graciously informing the user:
"Pardon me, I hate to bother you, but it seems that I have just determined that my right foot is missing. The gun in my left hand seems to have gone off at a most inconvenient moment and, well, what it boils down to is this: I am about to die. But before doing so I have carefully set-down the airplane in this somewhat out-of-the-way but safe landing field, and called a taxicab which will be shortl...."
Your code died (it couldn't exactly avoid it, since there's a bug somewhere...) but it did so under its own terms.
- You will need to check for session-expiration, but you can also do that "under your own terms" by checking for the existence of some dummy-variable in the Session struct. Doesn't matter what its name or value is (I use "exists"), only that it ... well ... exists. If it doesn't, then it means that the session is gone (or could not be established). So, make that check first, at the top of your code, and "go somewhere appropriate" if it's not there. Any other instance where "a session-variable is not what you expected" is therefore "a bug," which you "catch" as described above.