Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Ok, this is what I'm working on. Surprisingly, I was thinking of something along the lines you mentioned Zamezela ... I haven't got it working yet, but I think this should work.</p> <p>My user table:</p> <pre><code>CREATE TABLE "user" ( id serial NOT NULL, "userRoleId" integer NOT NULL, "employeeId" bigint NOT NULL, "subjectId" bigint NOT NULL, username text NOT NULL, cryptpwd text NOT NULL, "userStatusId" integer NOT NULL, md5pwd text NOT NULL, "loggedIn" boolean NOT NULL DEFAULT false, CONSTRAINT pk_user PRIMARY KEY (id), CONSTRAINT "subjectId" FOREIGN KEY ("subjectId") REFERENCES subject (id) MATCH FULL ON UPDATE RESTRICT ON DELETE RESTRICT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT user_employee_id FOREIGN KEY ("employeeId") REFERENCES employee (id) MATCH FULL ON UPDATE RESTRICT ON DELETE RESTRICT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT "user_userRole_id" FOREIGN KEY ("userRoleId") REFERENCES "userRole" (id) MATCH FULL ON UPDATE RESTRICT ON DELETE RESTRICT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT "user_userStatus_id" FOREIGN KEY ("userStatusId") REFERENCES "userStatus" (id) MATCH FULL ON UPDATE RESTRICT ON DELETE RESTRICT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT "unique_user_userName" UNIQUE (username) ) </code></pre> <p>I've created a table that records each and every user login. Will help track down on user activity:</p> <pre><code>CREATE TABLE "userLoginHistory" ( "userId" integer NOT NULL, _datetime timestamp without time zone NOT NULL, hostname text NOT NULL, "osUsername" text NOT NULL, id bigserial NOT NULL, CONSTRAINT "pk_userLoginHistory" PRIMARY KEY (id), CONSTRAINT "userLoginHistory_user_id" FOREIGN KEY ("userId") REFERENCES "user" (id) MATCH FULL ON UPDATE RESTRICT ON DELETE RESTRICT DEFERRABLE INITIALLY IMMEDIATE ) </code></pre> <p>I now have three main Stored functions thus far ... may add on to them tomorrow. Getting late.</p> <p>First one involves requesting for a user login. This returns the user id, role, whether someone is logged on on this user account, and whether this user is active:</p> <pre><code>create type userLoginRequestReturnType as ( userId integer, -- user.id userRoleId integer, -- user.roleId loggedIn boolean, -- user.loggedIn userActive boolean -- whether user is active ); CREATE OR REPLACE FUNCTION "user_login_request"(usernameIn text, passwordIn text) returns setof userLoginRequestReturnType as $$ declare user_Id integer; user_RoleId integer; user_StatusId integer; user_loggedIn boolean; user_Active boolean; sql text; begin user_Active = false; select into user_Id, user_RoleId, user_StatusId, user_loggedIn id, "userRoleId", "userStatusId", "loggedIn" from "user" where username = usernameIn and cryptpwd = crypt(passwordIn, cryptpwd); if (user_id &gt; 0) then -- record found select into user_Active "user_is_active"(user_StatusId); else user_id = 0; user_RoleId = 0; user_loggedIn = false; user_Active = false; end if; sql = 'select ' || user_Id || ', ' || user_RoleId || ', ' || user_loggedIn || ', ' || user_Active ||';'; return query execute sql; end; $$ language 'plpgsql'; </code></pre> <p>This is passed to the front end. If user_loggedIn is true, and all the other attributes support a successful log in, then the front end will notify the user that there is an existing connection, and whether to continue (disconnecting the existing connection). If it is false, then it just continues (without any prompt) to this function:</p> <pre><code>CREATE OR REPLACE FUNCTION "user_login_complete"(userIdIN integer, hostnameIN text, osUsernameIN text) returns bigint as $$ declare currentTime timestamp without time zone; userLoginHistoryId bigint; begin -- update user.loggedIn update "user" set "loggedIn" = true where id = userIdIN; -- insert into userLoginHistory currentTime = NOW()::timestamp without time zone; insert into "userLoginHistory" ("userId", _datetime, hostname, "osUsername") values (userIdIN, currentTime, hostnameIN, osUsernameIN); select into userLoginHistoryId currval('"userLoginHistory_id_seq"'); return userLoginHistoryId; end; $$ language 'plpgsql'; </code></pre> <p>The userLoginHistoryId is stored on the front end, since I'm using an MVC architecture for my Java Swing project, my abstract Model Class will call the following function in its constructor. I have taken your advice and will close the connection in each method.</p> <pre><code>-- function to check if the current logged in session is the last one recorded in database -- to be run before each connection to the database as per userId -- new userLoginHistoryId must be inserted into table userLoginHistory, and the id PK value stored in the front end -- -- returns: true, if current session is the last session recorded in table userLoginHistory for this user_autosuggest_by_ID -- : false, if another login session has been recorded. -- MUST BE EXECUTED BEFORE EACH AND EVERY DATABASE TRANSACTION!!!!! CREATE OR REPLACE FUNCTION "user_login_session_check"(userIdIN integer, userLoginHistoryIdIN bigint) returns boolean as $$ declare results boolean; userLoginHistoryId bigint; begin results = true; select into userLoginHistoryId id from "userLoginHistory" where "userId" = userIdIN ORDER BY id DESC LIMIT 1; if (userLoginHistoryIdIN = userLoginHistoryId) then results = true; else results = false; end if; end; $$ language 'plpgsql'; </code></pre> <p>Will test tomorrow and hopefully it works fine. Please feel free to comment.</p> <p>Thanks.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload