-- LegacyWorlds Beta 6 -- PostgreSQL database scripts -- -- Functions that extract event data from the queue tables -- and store them in the long term storage tables. -- -- Copyright(C) 2004-2012, DeepClone Development -- -------------------------------------------------------- /* * Entity fields table * ------------------- * * This table, which is filled when the database is created, associates entity * types with fields in the events.field_values table. */ DROP TABLE IF EXISTS events._entity_fields; CREATE TABLE events._entity_fields( efdef_entity events.entity_field_type NOT NULL PRIMARY KEY , field_name NAME NOT NULL , field_type NAME NOT NULL ); INSERT INTO events._entity_fields VALUES ( 'EMP' , 'empire_id' , 'INT' ) , ( 'PLN' , 'planet_id' , 'INT' ) , ( 'FLT' , 'fleet_id' , 'BIGINT' ) , ( 'ALL' , 'alliance_id' , 'INT' ) , ( 'BAT' , 'battle_id' , 'BIGINT' ) , ( 'ADM' , 'admin_id' , 'INT' ) , ( 'BUG' , 'bug_report_id' , 'BIGINT' ); /* * Process a pending event * ----------------------- * * /!\ INTERNAL FUNCTION /!\ * * This procedure processes a single row from an event queue. * * If the specified event identifier actually exists in the queue, it is * converted and stored in the main events tables, then the queue entry is * removed. * * In all cases, the entry is deleted from events.pending_events. * * Parameters: * _event_id The event's identifier * _evdef_id The event's type * * Returns: * ??? TRUE */ DROP FUNCTION IF EXISTS events.eq_process_event( BIGINT , TEXT ); CREATE FUNCTION events.eq_process_event( _event_id BIGINT , _evdef_id TEXT ) RETURNS BOOLEAN LANGUAGE PLPGSQL STRICT VOLATILE SECURITY INVOKER AS $eq_process_event$ DECLARE _tbl TEXT; _qstr TEXT; _qentry RECORD; _nfound INT; _efdef RECORD; BEGIN _tbl := 'events.eq_' || replace( _evdef_id , '-' , '_' ); _qstr := 'SELECT event_rtime , event_gtime , empire_id FROM ' || _tbl || ' WHERE event_id = $1'; EXECUTE _qstr INTO _qentry USING _event_id; GET DIAGNOSTICS _nfound = ROW_COUNT; IF _nfound > 0 THEN INSERT INTO events.events_v2 ( event_id , evdef_id , event_rtime , event_gtime , empire_id ) VALUES ( _event_id , _evdef_id , _qentry.event_rtime , _qentry.event_gtime , _qentry.empire_id ); _qstr := format( $field_acquisition$ SELECT efdef_id , field_name , field_type , ( efdef_type = 'I18N') AS i18n , _sq1.value FROM events.field_definitions INNER JOIN ( SELECT (each(hstore(_tbl))).* FROM %s _tbl WHERE _tbl.event_id = $1 ) _sq1 ON _sq1.key = 'ef_' || replace(efdef_id , '-','_') LEFT OUTER JOIN events._entity_fields USING ( efdef_entity ) WHERE evdef_id = $2 $field_acquisition$ , _tbl ); FOR _efdef IN EXECUTE _qstr USING _event_id , _evdef_id LOOP _qstr := 'INSERT INTO events.field_values(event_id,evdef_id,efdef_id,efval_litteral' || ( CASE WHEN _efdef.field_name IS NOT NULL THEN ',' || _efdef.field_name WHEN _efdef.i18n THEN ',string_id' ELSE '' END ) || ') '; IF _efdef.i18n THEN _qstr := _qstr || $i18n_query$ SELECT $1,$2,$3,_str.id::TEXT||' '||_str.name,_str.id FROM defs.strings _str WHERE _str.name = $4 $i18n_query$; ELSIF _efdef.field_name IS NOT NULL THEN _qstr := _qstr || format( 'VALUES($1,$2,$3,$4,$4::%s)' , _efdef.field_type ); ELSE _qstr := _qstr || 'VALUES($1,$2,$3,$4)'; END IF; EXECUTE _qstr USING _event_id , _evdef_id , _efdef.efdef_id , _efdef.value; END LOOP; END IF; DELETE FROM events.pending_events WHERE event_id = _event_id; RETURN TRUE; END; $eq_process_event$; REVOKE EXECUTE ON FUNCTION events.eq_process_event( BIGINT , TEXT ) FROM PUBLIC; /* * Process pending events * ---------------------- * * This procedure processes events from the queues. Each time the procedure is * called, it will process at most "game.events.batchSize" events. * * Returns: * ??? TRUE if events were processed, FALSE if the queues are * empty */ DROP FUNCTION IF EXISTS events.eq_process( ); CREATE FUNCTION events.eq_process( ) RETURNS BOOLEAN LANGUAGE PLPGSQL STRICT VOLATILE SECURITY DEFINER AS $eq_process$ DECLARE _limit INT; BEGIN _limit := sys.get_constant( 'game.events.batchSize' ); PERFORM events.eq_process_event( event_id , evdef_id ) FROM events.pending_events LIMIT _limit; RETURN FOUND; END; $eq_process$; REVOKE EXECUTE ON FUNCTION events.eq_process( ) FROM PUBLIC; GRANT EXECUTE ON FUNCTION events.eq_process( ) TO :dbuser;