# (C) Copyright 2008-2010 Nuxeo SA (http://nuxeo.com/) and contributors.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the GNU Lesser General Public License
# (LGPL) version 2.1 which accompanies this distribution, and is available at
# http://www.gnu.org/licenses/lgpl.html
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# Contributors:
#     Florent Guillaume
#     Benoit Delbosc

# Variables used:
# ${idType} VARCHAR(36)
# ${h2Functions} org.nuxeo.ecm.core.storage.sql.db.H2Functions
# ${h2Fulltext} org.nuxeo.ecm.core.storage.sql.db.H2Fulltext
# ${readPermissions} ('Browse'), ('Read'), ('ReadProperties'), ('ReadRemove'), ('ReadWrite'), ('Everything')

# Conditions used:
# fulltextEnabled

############################################################


#CATEGORY: beforeTableCreation


CREATE ALIAS IF NOT EXISTS NX_IN_TREE FOR "${h2Functions}.isInTreeString";

CREATE ALIAS IF NOT EXISTS NX_ACCESS_ALLOWED FOR "${h2Functions}.isAccessAllowedString";

CREATE ALIAS IF NOT EXISTS NX_CLUSTER_INVAL FOR "${h2Functions}.clusterInvalidateString";

CREATE ALIAS IF NOT EXISTS NX_CLUSTER_GET_INVALS FOR "${h2Functions}.getClusterInvalidationsString";

CREATE ALIAS IF NOT EXISTS nx_get_read_acl FOR "${h2Functions}.getReadAcl";

CREATE ALIAS IF NOT EXISTS nx_get_read_acls_for FOR "${h2Functions}.getReadAclsFor";

CREATE ALIAS IF NOT EXISTS nx_rebuild_read_acls FOR "${h2Functions}.rebuildReadAcls";

CREATE ALIAS IF NOT EXISTS nx_update_read_acls FOR "${h2Functions}.updateReadAcls";

#IF: fulltextEnabled
CREATE ALIAS IF NOT EXISTS NXFT_INIT FOR "${h2Fulltext}.init";

#IF: fulltextEnabled
CALL NXFT_INIT();


############################################################


#CATEGORY: afterTableCreation


# table to store canonical read acls
CREATE TABLE IF NOT EXISTS read_acls (
  id VARCHAR(4096) PRIMARY KEY,
  acl VARCHAR(4096)
);


# table to maintain a read acl for each hierarchy entry
CREATE TABLE IF NOT EXISTS hierarchy_read_acl (
  id ${idType} PRIMARY KEY,
  acl_id VARCHAR(4096),
  CONSTRAINT hierarchy_read_acl_id_fk FOREIGN KEY (id) REFERENCES hierarchy(id) ON DELETE CASCADE
);

# add index
CREATE INDEX IF NOT EXISTS hierarchy_read_acl_acl_id_idx ON hierarchy_read_acl(acl_id);


# log hierarchy with updated read acl
CREATE TABLE IF NOT EXISTS hierarchy_modified_acl (
  id ${idType},
  is_new boolean
);

# dump browse permission into a table
CREATE TABLE IF NOT EXISTS read_acl_permissions (
  permission VARCHAR(250)
);

#TEST:
SELECT 1 FROM read_acl_permissions;

#IF: emptyResult
INSERT INTO read_acl_permissions VALUES ${readPermissions};


DROP TRIGGER IF EXISTS nx_trig_acls_modified;

CREATE TRIGGER nx_trig_acls_modified
  AFTER INSERT, UPDATE, DELETE ON acls
  FOR EACH ROW CALL "${h2Functions}$LogAclsModified";

DROP TRIGGER IF EXISTS nx_trig_hierarchy_modified;

CREATE TRIGGER nx_trig_hierarchy_modified
  AFTER INSERT, UPDATE ON hierarchy
  FOR EACH ROW CALL "${h2Functions}$LogHierarchyModified";


# build the read acls if empty, this takes care of the upgrade
#TEST:
SELECT 1 FROM read_acls LIMIT 1;

#IF: emptyResult
SELECT * FROM nx_rebuild_read_acls();


DROP TRIGGER IF EXISTS NX_TRIG_DESC;

# ##### upgrade tag / nxp_tagging (since Nuxeo 5.3.2) #####

#TEST:
SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'NXP_TAGGING';

#IF: ! emptyResult
LOG.INFO Upgrading tags

# make tags placeless

#IF: ! emptyResult
UPDATE hierarchy SET parentid = NULL WHERE primarytype = 'Tag' AND isproperty = 0;

# make tagging hierarchy

#IF: ! emptyResult
UPDATE nxp_tagging SET id = random_uuid();

#IF: ! emptyResult
INSERT INTO hierarchy (id, name, isproperty, primarytype)
  SELECT tg.id, t.label, 0, 'Tagging'
    FROM nxp_tagging tg
    JOIN tag t ON tg.tag_id = t.id;

# make tagging relation

#IF: ! emptyResult
INSERT INTO relation (id, source, target)
  SELECT id, document_id, tag_id FROM nxp_tagging;

# make tagging dublincore (save is_private into coverage just in case)

#IF: ! emptyResult
INSERT INTO dublincore (id, title, creator, created, coverage)
  SELECT tg.id, t.label, tg.author, tg.creation_date, tg.is_private
    FROM nxp_tagging tg
    JOIN tag t ON tg.tag_id = t.id;

# drop now useless table

#IF: ! emptyResult
DROP TABLE nxp_tagging;

# remove old tags root

#IF: ! emptyResult
DELETE FROM hierarchy
  WHERE name = 'tags' AND primarytype = 'HiddenFolder' AND isproperty = 0
    AND parentid IN (SELECT id FROM hierarchy WHERE primarytype = 'Root' AND isproperty = 0);


############################################################


#CATEGORY: addClusterNode

# delete nodes for sessions that don't exist anymore, and old node for this
# session (session ids are recycled)
DELETE FROM cluster_nodes N WHERE
  NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.SESSIONS S WHERE N.nodeid = S.ID)
  OR N.nodeid = SESSION_ID()

INSERT INTO cluster_nodes (nodeid, created) VALUES (SESSION_ID(), CURRENT_TIMESTAMP);


#CATEGORY: removeClusterNode

DELETE FROM cluster_nodes WHERE nodeid = SESSION_ID();

