2014-05-05 23:13:06 +08:00
|
|
|
-- Return the estimated size of user data. Used for quota checking.
|
|
|
|
CREATE OR REPLACE FUNCTION CDB_UserDataSize()
|
|
|
|
RETURNS bigint AS
|
|
|
|
$$
|
|
|
|
-- TODO: double check this query. Maybe use CDB_TableMetadata for lookup ?
|
|
|
|
-- also, it's "table_name" sounds sensible to search_path
|
|
|
|
--
|
|
|
|
-- NOTE: division by 2 is an hack for the_geom_webmercator
|
|
|
|
--
|
|
|
|
SELECT coalesce(int8(sum(pg_total_relation_size(quote_ident(table_name))) / 2), 0)
|
|
|
|
AS quota
|
|
|
|
FROM information_schema.tables
|
|
|
|
WHERE table_catalog = current_database() AND table_schema = 'public'
|
|
|
|
AND table_name != 'spatial_ref_sys'
|
|
|
|
AND table_name != 'cdb_tablemetadata'
|
|
|
|
AND table_type = 'BASE TABLE';
|
|
|
|
$$
|
|
|
|
LANGUAGE 'sql' VOLATILE;
|
|
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION CDB_CheckQuota()
|
|
|
|
RETURNS trigger AS
|
|
|
|
$$
|
|
|
|
DECLARE
|
|
|
|
|
|
|
|
pbfact float8;
|
|
|
|
qmax int8;
|
|
|
|
dice float8;
|
|
|
|
quota float8;
|
|
|
|
BEGIN
|
|
|
|
|
|
|
|
pbfact := TG_ARGV[0];
|
|
|
|
dice := random();
|
|
|
|
|
|
|
|
-- RAISE DEBUG 'CDB_CheckQuota enter: pbfact=% dice=%', pbfact, dice;
|
|
|
|
|
|
|
|
IF dice < pbfact THEN
|
|
|
|
RAISE DEBUG 'Checking quota on table % (dice:%, needed:<%)', TG_RELID::text, dice, pbfact;
|
2014-05-12 19:37:47 +08:00
|
|
|
BEGIN
|
|
|
|
qmax := public._CDB_UserQuotaInBytes();
|
|
|
|
EXCEPTION WHEN undefined_function THEN
|
|
|
|
IF TG_NARGS > 1 THEN
|
|
|
|
RAISE NOTICE 'Using quota specified via trigger parameter';
|
|
|
|
qmax := TG_ARGV[1];
|
|
|
|
ELSE
|
|
|
|
RAISE EXCEPTION 'Missing _CDB_UserQuotaInBytes(), and no quota provided as parameter';
|
|
|
|
END IF;
|
|
|
|
END;
|
2014-05-08 23:14:06 +08:00
|
|
|
|
|
|
|
IF qmax = 0 THEN
|
|
|
|
RETURN NEW;
|
|
|
|
END IF;
|
|
|
|
|
2014-05-05 23:13:06 +08:00
|
|
|
SELECT CDB_UserDataSize() INTO quota;
|
|
|
|
IF quota > qmax THEN
|
|
|
|
RAISE EXCEPTION 'Quota exceeded by %KB', (quota-qmax)/1024;
|
|
|
|
ELSE RAISE DEBUG 'User quota in bytes: % < % (max allowed)', quota, qmax;
|
|
|
|
END IF;
|
|
|
|
-- ELSE RAISE DEBUG 'Not checking quota on table % (dice:%, needed:<%)', TG_RELID::text, dice, pbfact;
|
|
|
|
END IF;
|
|
|
|
|
|
|
|
RETURN NEW;
|
|
|
|
END;
|
|
|
|
$$
|
|
|
|
LANGUAGE 'plpgsql' VOLATILE;
|
2014-05-08 23:14:06 +08:00
|
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION CDB_SetUserQuotaInBytes(bytes int8)
|
|
|
|
RETURNS int8 AS
|
|
|
|
$$
|
|
|
|
DECLARE
|
|
|
|
current_quota int8;
|
|
|
|
sql text;
|
|
|
|
BEGIN
|
|
|
|
BEGIN
|
2014-05-08 23:20:40 +08:00
|
|
|
current_quota := public._CDB_UserQuotaInBytes();
|
2014-05-08 23:14:06 +08:00
|
|
|
EXCEPTION WHEN undefined_function THEN
|
|
|
|
current_quota := 0;
|
|
|
|
END;
|
|
|
|
|
2014-05-08 23:20:40 +08:00
|
|
|
sql := 'CREATE OR REPLACE FUNCTION public._CDB_UserQuotaInBytes() '
|
2014-05-08 23:14:06 +08:00
|
|
|
|| 'RETURNS int8 AS $X$ SELECT ' || bytes
|
|
|
|
|| '::int8 $X$ LANGUAGE sql IMMUTABLE';
|
|
|
|
EXECUTE sql;
|
|
|
|
|
|
|
|
return current_quota;
|
|
|
|
|
|
|
|
END
|
|
|
|
$$
|
|
|
|
LANGUAGE 'plpgsql' VOLATILE STRICT;
|