From d246f221f0d012d933c987362402119adb65d572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Tue, 3 Jul 2012 10:32:15 +0200 Subject: [PATCH] Event database access Added tables that store event access interfaces and event states per interface, as well as functions which allow events to be retrieved: * events.interfaces lists access interfaces, * events.unprocessed_events lists events which haven't been processed for each type of interface, with a "pre-processed" flag * events.ep_read() is a set of function variants which will read events * events.ep_access() is a set of function variants which read events then update their states. --- .../parts/030-data/170-events.sql | 60 ++ .../parts/040-functions/173-event-access.sql | 724 ++++++++++++++++++ 2 files changed, 784 insertions(+) create mode 100644 legacyworlds-server-data/db-structure/parts/040-functions/173-event-access.sql diff --git a/legacyworlds-server-data/db-structure/parts/030-data/170-events.sql b/legacyworlds-server-data/db-structure/parts/030-data/170-events.sql index 356d9e2..77fc97c 100644 --- a/legacyworlds-server-data/db-structure/parts/030-data/170-events.sql +++ b/legacyworlds-server-data/db-structure/parts/030-data/170-events.sql @@ -402,6 +402,66 @@ ALTER TABLE events.field_values GRANT SELECT ON events.field_values TO :dbuser; +/* + * Event viewing interfaces + * ------------------------ + * + * This table stores the list of interfaces which can be used to access the + * events. It allows the system to handle multiple types of event viewing or + * processing: for example the web interface and email notifications. + */ +CREATE TABLE events.interfaces( + + /* A short string that identifies the interface */ + evi_id VARCHAR(8) NOT NULL PRIMARY KEY , + + /* A description of the interface */ + evi_descr TEXT NOT NULL + +); + +/* Directly insert interface types */ +INSERT INTO events.interfaces( evi_id , evi_descr ) VALUES + ( 'game' , 'The game''s main interface' ) , + ( 'mail' , 'The e-mail notifications system' ); + + +/* + * Events to process + * ----------------- + * + * This table stores the list of events which need to be processed for each + * interface. + */ +CREATE TABLE events.unprocessed_events( + /* The event's identifier */ + event_id BIGINT NOT NULL , + + /* The interface's identifier */ + evi_id VARCHAR(8) NOT NULL , + + /* Whether the interface has pre-processed the event, but not displayed + * or sent it yet. This is used with e.g. the email notification system, + * which waits for more events once a first event is ready. When the + * server restarts, the field is set back to FALSE. + */ + upe_preprocessed BOOLEAN NOT NULL + DEFAULT FALSE , + + /* Use both the event and interface as the primary key */ + PRIMARY KEY( event_id , evi_id ) +); + +CREATE INDEX idx_unprocessed_interface + ON events.unprocessed_events( evi_id ); + +ALTER TABLE events.unprocessed_events + ADD CONSTRAINT fk_unprocessed_event + FOREIGN KEY ( event_id ) REFERENCES events.events_v2 ( event_id ) + ON DELETE CASCADE , + ADD CONSTRAINT fk_unprocessed_interface + FOREIGN KEY ( evi_id ) REFERENCES events.interfaces ( evi_id ); + /* * OLD B6M1 CODE BELOW! diff --git a/legacyworlds-server-data/db-structure/parts/040-functions/173-event-access.sql b/legacyworlds-server-data/db-structure/parts/040-functions/173-event-access.sql new file mode 100644 index 0000000..3d0f6ea --- /dev/null +++ b/legacyworlds-server-data/db-structure/parts/040-functions/173-event-access.sql @@ -0,0 +1,724 @@ +-- LegacyWorlds Beta 6 +-- PostgreSQL database scripts +-- +-- Functions that read event data and update event +-- states on behalf of event viewing / processing +-- interfaces. +-- +-- Copyright(C) 2004-2012, DeepClone Development +-- -------------------------------------------------------- + + +/* + * SOME GENERAL DOCUMENTATION + * -------------------------- + * + * This file provides a few functions the server can use to access the events: + * + * The events.ep_read() function variants provide read-only access to the + * list. They may be used with or without a target (whether that target is an + * user or an empire), and they can be given an offset and a limit if partial + * selection is desired. ep_read() accepts the following parameters ("+" + * means that the parameter is required). + * + * + access interface identifier + * target identifier + * target is empire? + * + access processed events? + * + access preprocessed events? + * + access new events? + * offset of first event + * maximal amount of events + * + * The events.ep_access() function variants provide the same service, but will + * additionally update the events' state after reading them. ep_access() + * uses the same parameters as ep_read(), but adds two new mandatory parameters + * at the end: + * + * + mark preprocessed events as processed? + * + state to set for new events + */ + + + +/* + * Insert new events in unprocessed list + * ------------------------------------- + * + * This trigger function is used to insert new events into the list of + * unprocessed events for all interface types. + */ +DROP FUNCTION IF EXISTS events.tgf_insert_unprocessed( ) CASCADE; +CREATE FUNCTION events.tgf_insert_unprocessed( ) + RETURNS TRIGGER + LANGUAGE PLPGSQL + STRICT VOLATILE SECURITY DEFINER + AS $tgf_insert_unprocessed$ +BEGIN + INSERT INTO events.unprocessed_events( event_id , evi_id ) + SELECT NEW.event_id , evi_id + FROM events.interfaces; + RETURN NEW; +END; +$tgf_insert_unprocessed$; + +REVOKE EXECUTE + ON FUNCTION events.tgf_insert_unprocessed( ) + FROM PUBLIC; + +CREATE TRIGGER tg_insert_unprocessed + AFTER INSERT ON events.events_v2 + FOR EACH ROW EXECUTE PROCEDURE events.tgf_insert_unprocessed( ); + + +/* + * Event processing states + * ----------------------- + * + * This type serves as an indication of event processing state. + * + * Note: this type is not used for storage, only for access. + */ +DROP TYPE IF EXISTS events.processing_state CASCADE; +CREATE TYPE events.processing_state AS ENUM( + /* The event is new and hasn't been processed yet */ + 'NEW' , + + /* The event has been preprocessed */ + 'PRE' , + + /* The event has been fully processed */ + 'DONE' + ); + + +/* + * Event list entry + * ---------------- + * + * This type corresponds to entries of the event lists returned by + * events.ep_list_events(). + */ +DROP TYPE IF EXISTS events.ep_list_entry CASCADE; +CREATE TYPE events.ep_list_entry AS ( + /* The event's identifier */ + event_id BIGINT , + + /* The event type */ + evdef_id TEXT , + + /* The user's identifier */ + empire_id INT , + + /* The event's processing state */ + event_state events.processing_state +); + + +/* + * Build the events listing query + * ------------------------------ + * + * /!\ INTERNAL FUNCTION /!\ + * + * This procedure generates the query string used to extract events for a given + * set of parameters. + * + * Parameters: + * _check_emp TRUE if the query ought to check the events' target + * empire, FALSE if all empires should be returned + * _accept_old Whether processed events should be selected + * _accept_pre Whether preprocessed events should be selected + * _accept_new Whether unprocessed events should be selected + * + * Returns: + * ??? The query string + */ +DROP FUNCTION IF EXISTS events.ep_make_list_query( + BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN ); +CREATE FUNCTION events.ep_make_list_query( + _check_emp BOOLEAN , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN ) + RETURNS TEXT + LANGUAGE PLPGSQL + STRICT IMMUTABLE SECURITY INVOKER + AS $ep_make_list_query$ + +DECLARE + _qstr TEXT; + _wstr TEXT; + _need_or BOOLEAN; + +BEGIN + IF NOT ( _accept_old OR _accept_pre OR _accept_new ) + THEN + RAISE EXCEPTION 'No events accepted'; + END IF; + + _qstr := $sel_query$ + SELECT _evt.event_id ,_evt.evdef_id , _evt.empire_id , ( CASE + WHEN _upe.upe_preprocessed IS NULL + THEN 'DONE' + WHEN _upe.upe_preprocessed + THEN 'PRE' + ELSE + 'NEW' + END )::events.processing_state + FROM events.events_v2 _evt + LEFT OUTER JOIN events.unprocessed_events _upe + ON _upe.event_id = _evt.event_id AND _upe.evi_id = $1 + $sel_query$; + + IF _check_emp THEN + _wstr := '_evt.empire_id = $2'; + ELSE + _wstr := ''; + END IF; + + IF NOT ( _accept_old AND _accept_pre AND _accept_new ) + THEN + IF _wstr <> '' + THEN + _wstr := _wstr || ' AND '; + END IF; + _wstr := _wstr || '('; + + _need_or := FALSE; + IF _accept_old THEN + _wstr := _wstr || '_upe.event_id IS NULL'; + _need_or := TRUE; + END IF; + + IF _accept_pre THEN + IF _need_or THEN + _wstr := _wstr || ' OR '; + ELSE + _need_or := TRUE; + END IF; + _wstr := _wstr || '_upe.upe_preprocessed'; + END IF; + + IF _accept_new THEN + IF _need_or THEN + _wstr := _wstr || ' OR '; + END IF; + _wstr := _wstr || 'NOT _upe.upe_preprocessed'; + END IF; + + _wstr := _wstr || ')'; + END IF; + + IF _wstr <> '' + THEN + _qstr := _qstr || ' WHERE ' || _wstr; + END IF; + + _qstr := _qstr || ' ORDER BY _evt.event_id DESC'; + RETURN _qstr; +END; +$ep_make_list_query$; + +REVOKE EXECUTE + ON FUNCTION events.ep_make_list_query( + BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN ) + FROM PUBLIC; + + + +/* + * List events + * ----------- + * + * /!\ INTERNAL FUNCTION /!\ + * + * This procedure generates a list of events for some type of interface. + * + * Parameters: + * _evi_id Identifier of the interface accessing events + * _empire_id The identifier of the empire to get events for (may be NULL) + * _accept_old Whether processed events should be selected + * _accept_pre Whether preprocessed events should be selected + * _accept_new Whether unprocessed events should be selected + * + * Returns: + * the set of events + */ +DROP FUNCTION IF EXISTS events.ep_list_events( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN ); +CREATE FUNCTION events.ep_list_events( + _evi_id TEXT , + _empire_id INT , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN ) + RETURNS SETOF events.ep_list_entry + LANGUAGE PLPGSQL + CALLED ON NULL INPUT + STABLE SECURITY INVOKER + AS $ep_list_events$ + +DECLARE + _record events.ep_list_entry; + +BEGIN + FOR _record IN EXECUTE events.ep_make_list_query( + _empire_id IS NOT NULL , + _accept_old , _accept_pre , _accept_new ) + USING _evi_id , _empire_id + LOOP + RETURN NEXT _record; + END LOOP; +END; +$ep_list_events$; + +REVOKE EXECUTE + ON FUNCTION events.ep_list_events( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN ) + FROM PUBLIC; + + + +DROP TYPE IF EXISTS events.event_list_type CASCADE; +CREATE TYPE events.event_list_type AS ( + /* Identifier of the empire to which the event applies */ + empire_id INT , + + /* Identifier of the user who controls the empire */ + user_id INT , + + /* Selected language for the empire */ + lang_id TEXT , + + /* Numeric identifier of the event */ + event_id BIGINT , + + /* The event's processing state */ + event_state events.processing_state , + + /* Real time at which the event occurred */ + event_rtime TIMESTAMP WITHOUT TIME ZONE , + + /* Game time (tick identifier) at which the event occurred */ + event_gtime BIGINT , + + /* Event priority from either the definition or the custom priorities */ + event_priority INT , + + /* Type of the event */ + evdef_id TEXT , + + /* Internationalised string that contains the name of the event type; + * used when displaying priority settings. + */ + evdef_name TEXT , + + /* Internationalised string that contains the template to use when + * generating the output for a single event. + */ + evdef_template TEXT , + + /* Field name */ + efdef_id TEXT , + + /* Field value */ + field_value TEXT +); + + + +/* + * Main events listing function + * ---------------------------- + * + * /!\ INTERNAL FUNCTION /!\ + * + * This function contains the main code for event access. It is capable of + * selecting events based on their target and/or state, can limit the amount + * of events fetched or fetch them starting from some offset, and is capable + * of updating event states for selected events. + * + * Parameters: + * _evi_id The identifier of the interface accessing the events list + * _target_id An empire or user identifier (may be NULL) + * _target_is_emp Whether the specified identifier is an empire (TRUE) or an + * user. May be NULL. + * _accept_old Whether processed events should be selected + * _accept_pre Whether preprocessed events should be selected + * _accept_new Whether unprocessed events should be selected + * _offset Offset of the first event to obtain in the list. May be + * NULL. + * _limit Maximal amount of events to list. May be NULL. + * _clear_pre If TRUE, selected events that had been preprocessed will + * be marked as fully processed. May be NULL. + * _change_new The state to which new events should be set. May be NULL + * or 'NEW' if no changes are to be made. + * + * Returns: + * A set of events.event_list_type records + */ +DROP FUNCTION IF EXISTS events.ep_get_events_internal( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT , BOOLEAN , + events.processing_state ) CASCADE; +CREATE FUNCTION events.ep_get_events_internal( + _evi_id TEXT , + _target_id INT , + _target_is_emp BOOLEAN , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN , + _offset INT , + _limit INT , + _clear_pre BOOLEAN , + _change_new events.processing_state ) + RETURNS SETOF events.event_list_type + LANGUAGE PLPGSQL + CALLED ON NULL INPUT + VOLATILE SECURITY INVOKER + AS $ep_get_events_internal$ + +DECLARE + _sel_query TEXT; + _empire_id INT; + _record events.event_list_type; + +BEGIN + -- Get empire identifier if necessary + IF NOT _target_is_emp + THEN + SELECT INTO _empire_id _emp.name_id + FROM emp.empires _emp + INNER JOIN naming.empire_names _emp_name + ON _emp.name_id = _emp_name.id + WHERE _emp_name.owner_id = _target_id; + IF NOT FOUND + THEN + RETURN; + END IF; + ELSE + _empire_id := _target_id; + END IF; + + -- Generate event selection query + _sel_query := $sel_query$ + CREATE TEMPORARY TABLE ep_selected + ON COMMIT DROP + AS SELECT * FROM events.ep_list_events( + $1 , $2 , $3 , $4 , $5 ) + $sel_query$; + IF _offset >= 0 + THEN + _sel_query := _sel_query || ' OFFSET ' || _offset; + END IF; + IF _limit > 0 + THEN + _sel_query := _sel_query || ' LIMIT ' || _limit; + END IF; + + -- Select events + EXECUTE _sel_query + USING _evi_id , _empire_id , _accept_old , _accept_pre , _accept_new; + + -- Update event states if necessary + IF _clear_pre THEN + DELETE FROM events.unprocessed_events + WHERE event_id IN ( SELECT event_id FROM ep_selected ) + AND upe_preprocessed + AND evi_id = _evi_id; + END IF; + IF _change_new = 'DONE' + THEN + DELETE FROM events.unprocessed_events + WHERE event_id IN ( SELECT event_id FROM ep_selected ) + AND NOT upe_preprocessed + AND evi_id = _evi_id; + ELSIF _change_new = 'PRE' + THEN + UPDATE events.unprocessed_events _upe + SET upe_preprocessed = TRUE + FROM ep_selected _sel + WHERE _sel.event_id = _upe.event_id + AND NOT _upe.upe_preprocessed + AND _upe.evi_id = _evi_id; + END IF; + + -- Select and return event data + FOR _record IN + SELECT _sel.empire_id , _emp_name.owner_id AS user_id , + _lg.language AS lang_id , _sel.event_id , + _sel.event_state , _ev.event_rtime , _ev.event_gtime , + ( CASE + WHEN _cp.evcp_priority IS NULL + THEN _evdef.evdef_priority + ELSE + _cp.evcp_priority + END ) AS event_priority , + _evdef.evdef_id , _edns.name AS evdef_name , + _edts.name AS evdef_template , _fval.efdef_id , + _fval.efval_litteral AS field_value + FROM ep_selected _sel + INNER JOIN events.events_v2 _ev + USING ( event_id , evdef_id ) + INNER JOIN events.event_definitions _evdef + USING ( evdef_id ) + INNER JOIN naming.empire_names _emp_name + ON _emp_name.id = _sel.empire_id + INNER JOIN users.credentials _user + ON _user.address_id = _emp_name.owner_id + INNER JOIN defs.languages _lg + ON _lg.id = _user.language_id + INNER JOIN defs.strings _edns + ON _edns.id = _evdef.evdef_name_id + INNER JOIN defs.strings _edts + ON _edts.id = _evdef.evdef_template_id + LEFT OUTER JOIN events.field_values _fval + USING ( event_id , evdef_id ) + LEFT OUTER JOIN events.custom_priorities _cp + USING ( evdef_id , evdef_adjustable , address_id ) + LOOP + RETURN NEXT _record; + END LOOP; + + DROP TABLE ep_selected; +END; +$ep_get_events_internal$; + +REVOKE EXECUTE + ON FUNCTION events.ep_get_events_internal( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT , + BOOLEAN , events.processing_state ) + FROM PUBLIC; + + + +/* + * READ-ONLY EVENT ACCESS WRAPPERS + */ +DROP FUNCTION IF EXISTS events.ep_read( TEXT, BOOLEAN , BOOLEAN , BOOLEAN ); +CREATE FUNCTION events.ep_read( + _evi_id TEXT , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN ) + RETURNS SETOF events.event_list_type + LANGUAGE SQL + STRICT VOLATILE SECURITY DEFINER +AS $ep_read$ + SELECT * FROM events.ep_get_events_internal( $1 , NULL , NULL , $2 , $3 , + $4 , NULL , NULL , NULL , NULL ); +$ep_read$; + +REVOKE EXECUTE + ON FUNCTION events.ep_read( TEXT , BOOLEAN , BOOLEAN , BOOLEAN ) + FROM PUBLIC; +GRANT EXECUTE + ON FUNCTION events.ep_read( TEXT , BOOLEAN , BOOLEAN , BOOLEAN ) + TO :dbuser; + +DROP FUNCTION IF EXISTS events.ep_read( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN ); +CREATE FUNCTION events.ep_read( + _evi_id TEXT , + _target_id INT , + _target_is_emp BOOLEAN , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN ) + RETURNS SETOF events.event_list_type + LANGUAGE SQL + STRICT VOLATILE SECURITY DEFINER +AS $ep_read$ + SELECT * FROM events.ep_get_events_internal( $1 , $2 , $3 , $4 , $5 , $6 , + NULL , NULL , NULL , NULL ); +$ep_read$; + +REVOKE EXECUTE + ON FUNCTION events.ep_read( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN ) + FROM PUBLIC; +GRANT EXECUTE + ON FUNCTION events.ep_read( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN ) + TO :dbuser; + +DROP FUNCTION IF EXISTS events.ep_read( + TEXT, BOOLEAN , BOOLEAN , BOOLEAN , INT , INT ); +CREATE FUNCTION events.ep_read( + _evi_id TEXT , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN , + _offset INT , + _limit INT ) + RETURNS SETOF events.event_list_type + LANGUAGE SQL + STRICT VOLATILE SECURITY DEFINER +AS $ep_read$ + SELECT * FROM events.ep_get_events_internal( $1 , NULL , NULL , $2 , $3 , + $4 , $5 , $6 , NULL , NULL ); +$ep_read$; + +REVOKE EXECUTE + ON FUNCTION events.ep_read( + TEXT , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT ) + FROM PUBLIC; +GRANT EXECUTE + ON FUNCTION events.ep_read( + TEXT , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT ) + TO :dbuser; + +DROP FUNCTION IF EXISTS events.ep_read( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT ); +CREATE FUNCTION events.ep_read( + _evi_id TEXT , + _target_id INT , + _target_is_emp BOOLEAN , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN , + _offset INT , + _limit INT ) + RETURNS SETOF events.event_list_type + LANGUAGE SQL + STRICT VOLATILE SECURITY DEFINER +AS $ep_read$ + SELECT * FROM events.ep_get_events_internal( $1 , $2 , $3 , $4 , $5 , $6 , + $7 , $8 , NULL , NULL ); +$ep_read$; + +REVOKE EXECUTE + ON FUNCTION events.ep_read( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT ) + FROM PUBLIC; +GRANT EXECUTE + ON FUNCTION events.ep_read( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT ) + TO :dbuser; + + +/* + * EVENT ACCESS WRAPPERS WITH UPDATE CAPABILITIES + */ +DROP FUNCTION IF EXISTS events.ep_access( + TEXT, BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , events.processing_state ); +CREATE FUNCTION events.ep_access( + _evi_id TEXT , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN , + _clear_pre BOOLEAN , + _change_new events.processing_state ) + RETURNS SETOF events.event_list_type + LANGUAGE SQL + STRICT VOLATILE SECURITY DEFINER +AS $ep_access$ + SELECT * FROM events.ep_get_events_internal( $1 , NULL , NULL , $2 , $3 , + $4 , NULL , NULL , $5 , $6 ); +$ep_access$; + +REVOKE EXECUTE + ON FUNCTION events.ep_access( + TEXT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , + events.processing_state ) + FROM PUBLIC; +GRANT EXECUTE + ON FUNCTION events.ep_access( + TEXT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , + events.processing_state ) + TO :dbuser; + +DROP FUNCTION IF EXISTS events.ep_access( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , + events.processing_state ); +CREATE FUNCTION events.ep_access( + _evi_id TEXT , + _target_id INT , + _target_is_emp BOOLEAN , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN , + _clear_pre BOOLEAN , + _change_new events.processing_state ) + RETURNS SETOF events.event_list_type + LANGUAGE SQL + STRICT VOLATILE SECURITY DEFINER +AS $ep_access$ + SELECT * FROM events.ep_get_events_internal( $1 , $2 , $3 , $4 , $5 , $6 , + NULL , NULL , $7 , $8 ); +$ep_access$; + +REVOKE EXECUTE + ON FUNCTION events.ep_access( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , + BOOLEAN , events.processing_state ) + FROM PUBLIC; +GRANT EXECUTE + ON FUNCTION events.ep_access( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , + BOOLEAN , events.processing_state ) + TO :dbuser; + +DROP FUNCTION IF EXISTS events.ep_access( + TEXT, BOOLEAN , BOOLEAN , BOOLEAN , INT , INT , BOOLEAN , + events.processing_state ); +CREATE FUNCTION events.ep_access( + _evi_id TEXT , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN , + _offset INT , + _limit INT , + _clear_pre BOOLEAN , + _change_new events.processing_state ) + RETURNS SETOF events.event_list_type + LANGUAGE SQL + STRICT VOLATILE SECURITY DEFINER +AS $ep_access$ + SELECT * FROM events.ep_get_events_internal( $1 , NULL , NULL , $2 , $3 , + $4 , $5 , $6 , $7 , $8 ); +$ep_access$; + +REVOKE EXECUTE + ON FUNCTION events.ep_access( + TEXT , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT , BOOLEAN , + events.processing_state ) + FROM PUBLIC; +GRANT EXECUTE + ON FUNCTION events.ep_access( + TEXT , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT , BOOLEAN , + events.processing_state ) + TO :dbuser; + +DROP FUNCTION IF EXISTS events.ep_access( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT , BOOLEAN , + events.processing_state ); +CREATE FUNCTION events.ep_access( + _evi_id TEXT , + _target_id INT , + _target_is_emp BOOLEAN , + _accept_old BOOLEAN , + _accept_pre BOOLEAN , + _accept_new BOOLEAN , + _offset INT , + _limit INT , + _clear_pre BOOLEAN , + _change_new events.processing_state ) + RETURNS SETOF events.event_list_type + LANGUAGE SQL + STRICT VOLATILE SECURITY DEFINER +AS $ep_access$ + SELECT * FROM events.ep_get_events_internal( $1 , $2 , $3 , $4 , $5 , $6 , + $7 , $8 , $9 , $10 ); +$ep_access$; + +REVOKE EXECUTE + ON FUNCTION events.ep_access( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT, + BOOLEAN , events.processing_state ) + FROM PUBLIC; +GRANT EXECUTE + ON FUNCTION events.ep_access( + TEXT , INT , BOOLEAN , BOOLEAN , BOOLEAN , BOOLEAN , INT , INT , + BOOLEAN , events.processing_state ) + TO :dbuser;