-- Database: "oBrand"

DROP DATABASE "oBrand";

-- Role: obrand

DROP ROLE obrand;

CREATE ROLE obrand LOGIN
  ENCRYPTED PASSWORD 'md51e16472d06fb312d14e3001f44e9460e'
  NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;

CREATE DATABASE "oBrand"
  WITH OWNER = postgres
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       LC_COLLATE = 'C'
       LC_CTYPE = 'C'
       CONNECTION LIMIT = -1;
GRANT ALL ON DATABASE "oBrand" TO postgres;


GRANT CONNECT ON DATABASE "oBrand" TO obrand;
REVOKE ALL ON DATABASE "oBrand" FROM public;

ALTER DEFAULT PRIVILEGES
    GRANT INSERT, SELECT, UPDATE ON TABLES
    TO public;

ALTER DEFAULT PRIVILEGES
    GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLES
    TO postgres;



--




ALTER TABLE "profile" DROP CONSTRAINT IF EXISTS "profile_fk0";

ALTER TABLE "profile" DROP CONSTRAINT IF EXISTS "profile_fk1";

ALTER TABLE "venue" DROP CONSTRAINT IF EXISTS "venue_fk0";

ALTER TABLE "billing" DROP CONSTRAINT IF EXISTS "billing_fk0";

DROP TABLE IF EXISTS "logins";

DROP TABLE IF EXISTS "profile";

DROP TABLE IF EXISTS "company";

DROP TABLE IF EXISTS "venue";

DROP TABLE IF EXISTS "billing";

DROP TABLE IF EXISTS "master_beacons";

DROP TABLE IF EXISTS "pages";


CREATE TABLE "logins" (
	"id" serial NOT NULL,
	"username" varchar(100) NOT NULL UNIQUE,
	"email" varchar(150) NOT NULL UNIQUE,
	"password_hash" varchar(78) NOT NULL,
	"password_reset_token" varchar(128) UNIQUE,
	"uid" varchar(22) UNIQUE,
	CONSTRAINT logins_pk PRIMARY KEY ("id")
) WITH (
  OIDS=FALSE
);



CREATE TABLE "profile" (
	"id" serial NOT NULL,
	"uid" varchar(22) NOT NULL,
	"forename" varchar(75) NOT NULL,
	"surname" varchar(75) NOT NULL,
	"gender" int NOT NULL,
	"dob" DATE NOT NULL,
	"bio" TEXT NOT NULL,
	"member_of" varchar(22),
	CONSTRAINT profile_pk PRIMARY KEY ("id")
) WITH (
  OIDS=FALSE
);



CREATE TABLE "company" (
	"id" serial NOT NULL,
	"cid" varchar(22) not null,
	"company_name" varchar(100) NOT NULL,
	"address1" varchar(150) NOT NULL,
	"address2" varchar(150),
	"address3" varchar(150),
	"town" varchar(150) NOT NULL,
	"county" varchar(150),
	"postcode" varchar(12) NOT NULL,
	"country" int ,
	"pcontact" varchar(20) NOT NULL,
	"ocontact" varchar(20),
	"mobile" varchar(20) ,
	"email" varchar(150) NOT NULL,
	CONSTRAINT company_pk PRIMARY KEY ("id")
) WITH (
  OIDS=FALSE
);



CREATE TABLE "venue" (
	"id" serial NOT NULL,
	"venue_name" varchar(100) NOT NULL,
	"address1" varchar(150) NOT NULL,
	"address2" varchar(150),
	"address3" varchar(150),
	"town" varchar(150) NOT NULL,
	"county" varchar(150) ,
	"postcode" varchar(12) NOT NULL,
	"country" int ,
	"pcontact" varchar(20) NOT NULL,
	"ocontact" varchar(20) ,
	"mobile" varchar(20) ,
	"email" varchar(150) NOT NULL,
	"company_id" int NOT NULL,
	CONSTRAINT venue_pk PRIMARY KEY ("id")
) WITH (
  OIDS=FALSE
);



CREATE TABLE "billing" (
	"id" serial NOT NULL,
	"company_id" int NOT NULL,
	CONSTRAINT billing_pk PRIMARY KEY ("id")
) WITH (
  OIDS=FALSE
);



CREATE TABLE "master_beacons" (
	"id" bigint NOT NULL,
	"uid" uuid NOT NULL,
	CONSTRAINT master_beacons_pk PRIMARY KEY ("id")
) WITH (
  OIDS=FALSE
);

CREATE TABLE "pages"
(
    id serial NOT NULL,,
    cid VARCHAR(22),
    vid VARCHAR(22),
    pid VARCHAR(22),
    content INTEGER,
    title VARCHAR(100) NOT NULL,
    data JSONB NOT NULL,
	  CONSTRAINT pages_pk PRIMARY KEY ("id")
) WITH (
  OIDS=FALSE
);




ALTER TABLE "profile" ADD CONSTRAINT "profile_fk0" FOREIGN KEY ("uid") REFERENCES "logins"("uid");
--ALTER TABLE "profile" ADD CONSTRAINT "profile_fk1" FOREIGN KEY ("member_of") REFERENCES "company"("cid");

ALTER TABLE "venue" ADD CONSTRAINT "venue_fk0" FOREIGN KEY ("company_id") REFERENCES "company"("id");

ALTER TABLE "billing" ADD CONSTRAINT "billing_fk0" FOREIGN KEY ("company_id") REFERENCES "company"("id");

grant connect on database "oBrand" to obrand;

GRANT SELECT, UPDATE, INSERT, DELETE, TRIGGER ON TABLE public.logins TO obrand;

grant select, update on logins_id_seq to obrand;
grant select, update on profile_id_seq to obrand;
grant select, update on company_id_seq to obrand;
grant select, update on pages_pk to obrand;




-- Function Builder
--DROP FUNCTION insert_user(character varying,character varying,character varying,character varying);
DROP FUNCTION upsert_profile;

CREATE OR REPLACE FUNCTION insert_user( _username VARCHAR(100), _email VARCHAR(150),
                                          _passwordHash VARCHAR(78), _uid VARCHAR(22))
  RETURNS VOID AS
$$

BEGIN
  INSERT into logins(username, email, password_hash, uid) Values(_username,_email,_passwordHash,_uid);
END;
$$
LANGUAGE plpgsql;

  --

CREATE OR REPLACE FUNCTION upsert_profile(_uid    VARCHAR(22), _forename VARCHAR(75), _surname VARCHAR(75),
                                          _gender INTEGER, _dob DATE, _bio TEXT)
  RETURNS VOID AS
$$

BEGIN
  WITH upsert AS (UPDATE profile
  SET forename = _forename, surname = _surname, gender = _gender, dob = _dob, bio = _bio
  WHERE uid = _uid
  RETURNING *)
  INSERT INTO profile (uid, forename, surname, gender, dob, bio) SELECT
                                                                   _uid,
                                                                   _forename,
                                                                   _surname,
                                                                   _gender,
                                                                   _dob,
                                                                   _bio
                                                                 WHERE NOT EXISTS(SELECT *
                                                                                  FROM upsert);


END;
$$
LANGUAGE plpgsql;

--

;

--DROP FUNCTION upsert_profile(character varying,character varying,character varying,integer,date,text) ;

CREATE OR REPLACE FUNCTION upsert_company(
  _cid          VARCHAR(22),
  _company_name VARCHAR(100),
  _address1     VARCHAR(150),
  _address2     VARCHAR(150),
  _address3     VARCHAR(150),
  _town         VARCHAR(150),
  _county       VARCHAR(150),
  _postcode     VARCHAR(12),
  _country      INTEGER,
  _pcontact     VARCHAR(20),
  _ocontact     VARCHAR(20),
  _mobile       VARCHAR(20),
  _email        VARCHAR(150))

  RETURNS VOID AS
$$

BEGIN
  WITH upsert AS (UPDATE company
  SET cid        = _cid,
    company_name = _company_name,
    address1     = _address1,
    address2     = _address2,
    address3     = _address3,
    town         = _town,
    county       = _county,
    postcode     = _postcode,
    country      = _country,
    pcontact    = _pcontact,
    ocontact    = _ocontact,
    mobile       = _mobile,
    email        = _email

  WHERE cid = _cid
  RETURNING *)
  INSERT INTO company (
    cid,
    company_name,
    address1,
    address2,
    address3,
    town,
    county,
    postcode,
    country,
    pcontact,
    ocontact,
    mobile,
    email
  ) SELECT
      _cid,
      _company_name,
      _address1,
      _address2,
      _address3,
      _town,
      _county,
      _postcode,
      _country,
      _pcontact,
      _ocontact,
      _mobile,
      _email
    WHERE NOT EXISTS(SELECT *
                     FROM upsert);


END;
$$
LANGUAGE plpgsql;



--

;


CREATE OR REPLACE FUNCTION getAccountDetails(
  _uid VARCHAR(22))

  RETURNS TABLE(id INT, email VARCHAR(150), uid VARCHAR(22), forename VARCHAR(75), surname VARCHAR(75), member_of VARCHAR(22))

AS
$$

BEGIN

  RETURN QUERY
  SELECT

    logins.id,
    logins.email,
    logins.uid,
    profile.forename,
    profile.surname,
    profile.member_of
  FROM logins
    LEFT JOIN profile ON profile.uid = logins.uid
  WHERE logins.uid = _uid;

END;
$$
LANGUAGE plpgsql;



--

;

CREATE OR REPLACE FUNCTION makeMemberOf(_uid    VARCHAR(22), _cid VARCHAR(22))
  RETURNS VOID AS
$$

BEGIN
  UPDATE profile
  SET profile.member_of = _cid
  WHERE profile.uid = _uid;


END;
$$
LANGUAGE plpgsql;


--


;


CREATE OR REPLACE FUNCTION upsert_page(_cid    VARCHAR(22),
  _vid    VARCHAR(22), _pid    VARCHAR(22), _content INTEGER, _title VARCHAR(100), _data JSONB)
  RETURNS VOID AS
$$

BEGIN
  WITH upsert AS (UPDATE pages
  SET cid = _cid, vid = _vid, content = _content, title = _title, data = _data
  WHERE pid = _pid
  RETURNING *)
  INSERT INTO pages (cid, vid, pid, content, title, data) SELECT
                                                                   _cid,
                                                                   _vid,
                                                                   _pid,
                                                                   _content,
                                                                   _title,
                                                                   _data
                                                                 WHERE NOT EXISTS(SELECT *
                                                                                  FROM upsert);


END;
$$
LANGUAGE plpgsql;
