-- LegacyWorlds Beta 6 -- PostgreSQL database scripts -- -- Functions that access system constants -- -- Copyright(C) 2004-2010, DeepClone Development -- -------------------------------------------------------- -- -- Creates or gets a constant category -- -- Parameters: -- ccnm Constant category name -- -- Returns: -- the category's identifier -- CREATE OR REPLACE FUNCTION sys.cog_constant_category( ccnm TEXT ) RETURNS INT STRICT VOLATILE SECURITY INVOKER AS $$ DECLARE ccid INT; BEGIN BEGIN INSERT INTO sys.constant_categories (name) VALUES (ccnm) RETURNING id INTO ccid; EXCEPTION WHEN unique_violation THEN SELECT INTO ccid id FROM sys.constant_categories WHERE name = ccnm FOR UPDATE; END; RETURN ccid; END; $$ LANGUAGE plpgsql; -- -- Creates or updates a constant with no boundaries -- -- Parameters: -- cnm Constant name -- cdesc Constant description -- ccnm Constant category name -- dval Default value -- -- Returns: -- the constant's actual value -- CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL ) RETURNS REAL STRICT VOLATILE SECURITY DEFINER AS $$ DECLARE ccid INT; occid INT; cval REAL; BEGIN ccid := sys.cog_constant_category( ccnm ); BEGIN INSERT INTO sys.constant_definitions( name , category_id , description , c_value ) VALUES ( cnm , ccid , cdesc , dval ); cval := dval; EXCEPTION WHEN unique_violation THEN SELECT INTO occid , cval category_id , c_value FROM sys.constant_definitions WHERE name = cnm FOR UPDATE; UPDATE sys.constant_definitions SET category_id = ccid , description = cdesc , min_value = NULL , max_value = NULL WHERE name = cnm; IF occid <> ccid THEN BEGIN DELETE FROM sys.constant_categories WHERE id = occid; EXCEPTION WHEN foreign_key_violation THEN -- Do nothing END; END IF; END; RETURN cval; END; $$ LANGUAGE plpgsql; GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL ) TO :dbuser; -- -- Creates or updates a constant with a single boundary -- -- Parameters: -- cnm Constant name -- cdesc Constant description -- ccnm Constant category name -- dval Default value -- bval Bound value -- ismin Whether the bound value is the minimal or maximal value for the constant -- -- Returns: -- the constant's actual value -- CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL , bval REAL , ismin BOOLEAN ) RETURNS REAL STRICT VOLATILE SECURITY DEFINER AS $$ DECLARE ccid INT; occid INT; cval REAL; mival REAL; maval REAL; BEGIN IF ismin THEN mival := bval; maval := NULL; ELSE maval := bval; mival := NULL; END IF; ccid := sys.cog_constant_category( ccnm ); BEGIN INSERT INTO sys.constant_definitions( name , category_id , description , c_value , min_value , max_value ) VALUES ( cnm , ccid , cdesc , dval , mival , maval ); cval := dval; EXCEPTION WHEN unique_violation THEN SELECT INTO occid , cval category_id , c_value FROM sys.constant_definitions WHERE name = cnm FOR UPDATE; BEGIN UPDATE sys.constant_definitions SET category_id = ccid , description = cdesc , min_value = mival , max_value = maval WHERE name = cnm; EXCEPTION WHEN check_violation THEN UPDATE sys.constant_definitions SET category_id = ccid , description = cdesc , min_value = mival , max_value = maval , c_value = dval WHERE name = cnm; cval := dval; END; IF occid <> ccid THEN BEGIN DELETE FROM sys.constant_categories WHERE id = occid; EXCEPTION WHEN foreign_key_violation THEN -- Do nothing END; END IF; END; RETURN cval; END; $$ LANGUAGE plpgsql; GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , BOOLEAN ) TO :dbuser; -- -- Creates or updates a constant with both boundaries -- -- Parameters: -- cnm Constant name -- cdesc Constant description -- ccnm Constant category name -- dval Default value -- mival Minimal value -- maval Maximal value -- -- Returns: -- the constant's actual value -- CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL , mival REAL , maval REAL ) RETURNS REAL STRICT VOLATILE SECURITY DEFINER AS $$ DECLARE ccid INT; occid INT; cval REAL; BEGIN ccid := sys.cog_constant_category( ccnm ); BEGIN INSERT INTO sys.constant_definitions( name , category_id , description , c_value , min_value , max_value ) VALUES ( cnm , ccid , cdesc , dval , mival , maval ); cval := dval; EXCEPTION WHEN unique_violation THEN SELECT INTO occid , cval category_id , c_value FROM sys.constant_definitions WHERE name = cnm FOR UPDATE; BEGIN UPDATE sys.constant_definitions SET category_id = ccid , description = cdesc , min_value = mival , max_value = maval WHERE name = cnm; EXCEPTION WHEN check_violation THEN UPDATE sys.constant_definitions SET category_id = ccid , description = cdesc , min_value = mival , max_value = maval , c_value = dval WHERE name = cnm; cval := dval; END; IF occid <> ccid THEN BEGIN DELETE FROM sys.constant_categories WHERE id = occid; EXCEPTION WHEN foreign_key_violation THEN -- Do nothing END; END IF; END; RETURN cval; END; $$ LANGUAGE plpgsql; GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , REAL ) TO :dbuser; -- -- Updates a constant's value -- -- Parameters: -- cnm Constant name -- nval New value -- aid Administrator attempting to update the constant -- -- Returns: -- TRUE on success, FALSE on failure -- CREATE OR REPLACE FUNCTION sys.set_constant( cnm TEXT , nval REAL , aid INT ) RETURNS BOOLEAN STRICT VOLATILE SECURITY DEFINER AS $$ DECLARE success BOOLEAN; BEGIN BEGIN UPDATE sys.constant_definitions SET c_value = nval WHERE name = cnm; success := FOUND; EXCEPTION WHEN check_violation THEN success := FALSE; END; PERFORM admin.write_log( aid , 'INFO'::log_level , 'Constant "' || cnm || '" changed to ' || nval ); RETURN success; END; $$ LANGUAGE plpgsql; GRANT EXECUTE ON FUNCTION sys.set_constant( TEXT , REAL , INT ) TO :dbuser; -- -- Gets a constant's value -- -- Parameters: -- cnm Constant name -- CREATE OR REPLACE FUNCTION sys.get_constant( cnm TEXT ) RETURNS REAL STRICT STABLE SECURITY DEFINER AS $$ SELECT c_value FROM sys.constant_definitions WHERE name = $1; $$ LANGUAGE SQL; -- -- Constants view -- CREATE VIEW sys.constants_view AS SELECT cat.name AS category , cns.name AS name , cns.description AS description , cns.c_value AS value , cns.min_value AS min , cns.max_value AS max FROM sys.constant_definitions cns INNER JOIN sys.constant_categories cat ON cat.id = cns.category_id ORDER BY cat.name , cns.name; GRANT SELECT ON sys.constants_view TO :dbuser;