HEX
Server: Apache/2.4.63 (Unix)
System: Linux Synopilou92 4.4.302+ #72806 SMP Mon Jul 21 23:16:00 CST 2025 x86_64
User: pilou92 (1026)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: //var/packages/Spreadsheet/scripts/create_table.sql
BEGIN;

CREATE TABLE IF NOT EXISTS db_version (
	version NUMERIC NOT NULL
);

CREATE UNIQUE INDEX db_version_one_row ON db_version((version IS NOT NULL));

CREATE FUNCTION db_version_no_delete ()
RETURNS trigger
LANGUAGE plpgsql AS $f$
BEGIN
	RAISE EXCEPTION 'You may not delete the DB version!';
END; $f$;

CREATE TRIGGER db_version_no_delete
BEFORE DELETE ON db_version
FOR EACH ROW EXECUTE PROCEDURE db_version_no_delete();

INSERT INTO db_version (version) VALUES (11);

CREATE TABLE IF NOT EXISTS node (
	object_id TEXT UNIQUE NOT NULL,
	category TEXT DEFAULT 'node' NOT NULL,
	commit_msg JSON,
	brief TEXT,
	version TEXT NOT NULL,
	ctime BIGINT,
	mtime BIGINT,
	atime BIGINT,
	encrypt BOOLEAN DEFAULT FALSE,
	thumb TEXT,
	attachment JSON,
	link_id TEXT NOT NULL,
	ntype BIGINT NOT NULL,
	extra_info JSON
);

CREATE INDEX idx_node_ctime ON node(ctime);
CREATE INDEX idx_node_mtime ON node(mtime);
CREATE INDEX idx_node_atime ON node(atime);
CREATE INDEX idx_node_ntype ON node(ntype);

CREATE TABLE IF NOT EXISTS link (
	id TEXT UNIQUE NOT NULL,
	object_id TEXT NOT NULL,
	category TEXT NOT NULL,
	ntype BIGINT NOT NULL,
	CONSTRAINT link_mapper_ukey UNIQUE (id, object_id)
);

CREATE INDEX idx_link_object_id ON link(object_id);

CREATE TABLE IF NOT EXISTS notification (
	id  BIGSERIAL PRIMARY KEY,
	object_id TEXT NOT NULL,
	sender BIGINT NOT NULL,
	receiver BIGINT NOT NULL,
	time INTEGER NOT NULL DEFAULT 0,
	CONSTRAINT notification_mapper_ukey UNIQUE (object_id, sender, receiver)
);

CREATE OR REPLACE FUNCTION upsert_notification (_object_id TEXT, _sender BIGINT, _receiver BIGINT, _time BIGINT)
RETURNS INTEGER AS $$
DECLARE
	result INTEGER;
BEGIN
	BEGIN
		INSERT INTO notification (object_id, sender, receiver, time) VALUES (_object_id, _sender, _receiver, _time) RETURNING id INTO result;
		RETURN result;
	EXCEPTION WHEN unique_violation THEN
		UPDATE notification SET time=_time WHERE id IN (SELECT id FROM notification WHERE object_id=_object_id AND sender=_sender AND receiver=_receiver) AND ABS(_time - (SELECT COALESCE((SELECT time FROM notification WHERE object_id=_object_id AND sender=_sender AND receiver=_receiver), 0))) > 3600 RETURNING id INTO result;
		IF NOT FOUND THEN
			RETURN 0;
		END IF;
		RETURN result;
	END;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION afterNodeDeleted()
RETURNS "trigger" AS $$
	BEGIN
		DELETE FROM link WHERE object_id=OLD.object_id;
		DELETE FROM notification WHERE object_id=OLD.object_id;
		RETURN NULL;
	END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER "onDelete" AFTER DELETE
   ON node
   FOR EACH ROW
   EXECUTE PROCEDURE afterNodeDeleted();

CREATE TABLE IF NOT EXISTS mru_fc (
	id BIGSERIAL PRIMARY KEY,
	owner BIGINT NOT NULL,
	fc TEXT NOT NULL,
	order_sn INTEGER NOT NULL DEFAULT 0,
	CONSTRAINT mru_fc_mapper_ukey UNIQUE (owner, fc)
);
CREATE INDEX idx_mru_fc_owner ON mru_fc(owner);
CREATE INDEX idx_mru_fc_fc ON mru_fc(fc);
CREATE INDEX idx_mru_fc_order_sn ON mru_fc(order_sn);
CREATE INDEX idx_mru_fc_owner_fc ON mru_fc(owner, fc);

CREATE OR REPLACE FUNCTION upsert_mru_fc (_owner BIGINT, _fc TEXT)
RETURNS INTEGER AS $$
DECLARE
	first_try BOOLEAN := TRUE;
	result INTEGER;
	max_order INTEGER;
BEGIN
	LOOP
		SELECT COALESCE(MAX(order_sn), 0) + 1 INTO max_order FROM mru_fc WHERE owner = _owner;
		UPDATE mru_fc SET order_sn = max_order WHERE owner = _owner AND fc = _fc RETURNING id INTO result;
		IF found THEN
			RETURN result;
		END IF;
		BEGIN
			INSERT INTO mru_fc(owner, fc, order_sn) VALUES(_owner, _fc, max_order) RETURNING id INTO result;
			RETURN result;
		EXCEPTION WHEN unique_violation THEN
			IF (first_try = TRUE) THEN
				first_try := FALSE;
			ELSE
				RETURN 0;
			END IF;
		END;
	END LOOP;
END;
$$ LANGUAGE plpgsql;

COMMIT;