-- fn_get_audit_uid_by_username CREATE OR REPLACE FUNCTION @extschema@.fn_get_audit_uid_by_username ( in_username varchar ) returns integer as $_$ declare my_uid varchar; my_query varchar; my_user_table_uid_col varchar; my_user_table varchar; my_user_table_username_col varchar; begin select current_setting('cyanaudit.user_table'), current_setting('cyanaudit.user_table_uid_col'), current_setting('cyanaudit.user_table_username_col') into my_user_table, my_user_table_uid_col, my_user_table_username_col; if my_user_table = '' OR my_user_table_uid_col = '' OR my_user_table_username_col = '' then return null; end if; my_query := 'select ' || my_user_table_uid_col || ' from ' || my_user_table || ' where ' || my_user_table_username_col || ' = ''' || in_username || ''''; execute my_query into my_uid; return my_uid; exception when undefined_object then return null; when undefined_table then raise notice 'Cyan Audit: Invalid user_table'; return null; when undefined_column then raise notice 'Cyan Audit: Invalid user_table_uid_col or user_table_username_col'; return null; end $_$ language plpgsql stable strict; -- fn_get_or_create_audit_field CREATE OR REPLACE FUNCTION @extschema@.fn_get_or_create_audit_field ( in_table_name varchar, in_column_name varchar, in_audit_data_type integer default null ) returns integer as $_$ declare my_audit_field integer; my_active boolean; begin select audit_field into my_audit_field from @extschema@.tb_audit_field where table_name = in_table_name and column_name = in_column_name; -- if we do not yet know about the field if not found then -- set it active if another field in this table is already active select active into my_active from @extschema@.tb_audit_field where table_name = in_table_name order by active desc limit 1; -- If no columns of this table are known, -- or this table is currently being logged, if my_active is distinct from false then -- set it active if the column is currently real in the db select count(*)::integer::boolean into my_active from information_schema.columns where table_schema = 'public' and table_name = in_table_name and column_name = in_column_name; end if; insert into @extschema@.tb_audit_field ( table_name, column_name, active, audit_data_type ) values ( in_table_name, in_column_name, my_active, in_audit_data_type ) returning audit_field into my_audit_field; end if; return my_audit_field; end $_$ language 'plpgsql'; -- fn_update_audit_event_log_trigger_on_table CREATE OR REPLACE FUNCTION @extschema@.fn_update_audit_event_log_trigger_on_table ( in_table_name varchar ) returns void as $_$ use strict; my $table_name = $_[0]; return if $table_name =~ /tb_audit_.*/; my $table_q = "select relname " . " from pg_class c " . " join pg_namespace n " . " on c.relnamespace = n.oid " . " where n.nspname = 'public' " . " and c.relname = '$table_name' "; my $table_rv = spi_exec_query($table_q); if( $table_rv->{'processed'} == 0 ) { elog(NOTICE, "Cannot audit invalid table '$table_name'"); return; } my $colnames_q = "select audit_field, column_name " . " from @extschema@.tb_audit_field " . " where table_name = '$table_name' " . " and active = true "; my $colnames_rv = spi_exec_query($colnames_q); if( $colnames_rv->{'processed'} == 0 ) { my $q = "select @extschema@.fn_drop_audit_event_log_trigger('$table_name')"; eval{ spi_exec_query($q) }; elog(ERROR, "fn_drop_audit_event_log_trigger: $@") if($@); return; } my $pk_q = "select @extschema@.fn_get_table_pk_col('$table_name') as pk_col "; my $pk_rv = spi_exec_query($pk_q); my $pk_col = $pk_rv->{'rows'}[0]{'pk_col'}; unless( $pk_col ) { my $pk2_q = "select column_name as pk_col " . " from @extschema@.tb_audit_field " . " where table_pk = audit_field " . " and table_name = '$table_name'"; my $pk2_rv = spi_exec_query($pk2_q); $pk_col = $pk2_rv->{'rows'}[0]{'pk_col'}; unless( $pk_col ) { elog(NOTICE, "pk_col is null"); return; } } my $fn_q = <{'rows'}}) { my $column_name = $row->{'column_name'}; my $audit_field = $row->{'audit_field'}; $fn_q .= <