better_record 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +12 -18
- data/app/models/better_record/table_size.rb +30 -28
- data/config/initializers/{money_type.rb → active_record/money_type.rb} +0 -0
- data/config/initializers/{boolean.rb → core_ext/boolean.rb} +0 -0
- data/config/initializers/core_ext/date.rb +9 -0
- data/config/initializers/{integer.rb → core_ext/integer.rb} +0 -0
- data/config/initializers/dkim.rb +7 -0
- data/config/initializers/redis_store.rb +24 -0
- data/lib/better_record.rb +6 -4
- data/lib/better_record/engine.rb +7 -0
- data/lib/better_record/fake_redis.rb +94 -0
- data/lib/better_record/version.rb +1 -1
- data/lib/tasks/spec/attributes.rake +7 -1
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +4 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/test_audit.rb +2 -0
- data/spec/dummy/app/models/test_custom_audit.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +36 -0
- data/spec/dummy/bin/update +31 -0
- data/spec/dummy/bin/yarn +11 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +19 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +61 -0
- data/spec/dummy/config/environments/production.rb +94 -0
- data/spec/dummy/config/environments/test.rb +46 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/better_record.rb +42 -0
- data/{config → spec/dummy/config}/initializers/content_security_policy.rb +0 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +34 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/migrate/20180725233004_create_test_audits.rb +11 -0
- data/spec/dummy/db/migrate/20180725233007_create_test_custom_audits.rb +12 -0
- data/spec/dummy/db/migrate/20180725235254_create_better_record_db_functions.better_record.rb +95 -0
- data/spec/dummy/db/migrate/20180725235255_create_better_record_table_sizes.better_record.rb +25 -0
- data/spec/dummy/db/structure.sql +781 -0
- data/spec/dummy/lib/templates/active_record/model/model.rb +31 -0
- data/spec/dummy/lib/templates/rspec/model/model_spec.rb +17 -0
- data/spec/dummy/log/development.log +2495 -0
- data/spec/dummy/log/test.log +197 -0
- data/spec/dummy/package.json +5 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/spec/factories/test_audits.rb +7 -0
- data/spec/dummy/spec/factories/test_custom_audits.rb +8 -0
- data/spec/dummy/spec/models/test_audit_spec.rb +5 -0
- data/spec/dummy/spec/models/test_custom_audit_spec.rb +5 -0
- data/spec/factories/better_record_table_sizes.rb +16 -0
- data/spec/factories/test_audits.rb +7 -0
- data/spec/factories/test_custom_audits.rb +8 -0
- data/spec/lib/generators/better_record/install_generator_test.rb +16 -0
- data/spec/method_helper.rb +7 -0
- data/spec/method_helper/functions.rb +9 -0
- data/spec/method_helper/functions/boolean_column.rb +52 -0
- data/spec/method_helper/functions/has_valid_factory.rb +20 -0
- data/spec/method_helper/functions/optional_column.rb +17 -0
- data/spec/method_helper/functions/required_column.rb +35 -0
- data/spec/models/better_record/logged_action_spec.rb +35 -0
- data/spec/models/better_record/table_size_spec.rb +26 -0
- data/spec/models/test_audit_spec.rb +5 -0
- data/spec/models/test_custom_audit_spec.rb +5 -0
- data/spec/rails_helper.rb +36 -0
- data/spec/tmp/testes +0 -0
- metadata +204 -7
@@ -0,0 +1,7 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
4
|
+
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
|
5
|
+
|
6
|
+
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
|
7
|
+
# Rails.backtrace_cleaner.remove_silencers!
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module BetterRecord
|
2
|
+
##################################################################
|
3
|
+
# ALL SETTINGS HERE CAN BE SET THROUGH ENVIRONMENT VARIABLES #
|
4
|
+
# #
|
5
|
+
# default_polymorphic_method: BR_DEFAULT_POLYMORPHIC_METHOD #
|
6
|
+
# db_audit_schema: BR_DB_AUDIT_SCHEMA #
|
7
|
+
# has_audits_by_default: BR_ADD_HAS_MANY #
|
8
|
+
# audit_relation_name: BR_AUDIT_RELATION_NAME #
|
9
|
+
# layout_template: BR_LAYOUT_TEMPLATE #
|
10
|
+
# app_domain_name: APP_DOMAIN_NAME #
|
11
|
+
##################################################################
|
12
|
+
|
13
|
+
# uncomment the following line to use table_names instead of model names
|
14
|
+
# as the 'type' value in polymorphic relationships
|
15
|
+
|
16
|
+
# self.default_polymorphic_method = :polymorphic_name
|
17
|
+
|
18
|
+
# uncomment the following line to use change the database schema
|
19
|
+
# for auditing functions and logged_actions. DEFAULT - 'auditing'
|
20
|
+
|
21
|
+
# self.db_audit_schema = 'audit'
|
22
|
+
|
23
|
+
# uncomment the following line to add an association for table audits
|
24
|
+
# directly to ActiveRecord::Base. DEFAULT - false
|
25
|
+
|
26
|
+
# self.has_audits_by_default = true
|
27
|
+
|
28
|
+
# uncomment the following line to change the association name for
|
29
|
+
# auditing lookups. DEFAULT - :audits
|
30
|
+
|
31
|
+
# self.audit_relation_name = :logged_actions
|
32
|
+
|
33
|
+
# uncomment the following line to change the layout template used by
|
34
|
+
# BetterRecord::ActionController. DEFAULT - 'better_record/layout'
|
35
|
+
|
36
|
+
# self.layout_template = 'layout'
|
37
|
+
|
38
|
+
# uncomment the following line to set the domain your application
|
39
|
+
# runs under. Used in setting DKIM params. DEFAULT - 'non_existant_domain.com'
|
40
|
+
|
41
|
+
# self.app_domain_name = 'default_app_name.com'
|
42
|
+
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Add new inflection rules using the following format. Inflections
|
4
|
+
# are locale specific, and you may define rules for as many different
|
5
|
+
# locales as you wish. All of these examples are active by default:
|
6
|
+
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
7
|
+
# inflect.plural /^(ox)$/i, '\1en'
|
8
|
+
# inflect.singular /^(ox)en/i, '\1'
|
9
|
+
# inflect.irregular 'person', 'people'
|
10
|
+
# inflect.uncountable %w( fish sheep )
|
11
|
+
# end
|
12
|
+
|
13
|
+
# These inflection rules are supported but not enabled by default:
|
14
|
+
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
15
|
+
# inflect.acronym 'RESTful'
|
16
|
+
# end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# This file contains settings for ActionController::ParamsWrapper which
|
4
|
+
# is enabled by default.
|
5
|
+
|
6
|
+
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
wrap_parameters format: [:json]
|
9
|
+
end
|
10
|
+
|
11
|
+
# To enable root element in JSON for ActiveRecord objects.
|
12
|
+
# ActiveSupport.on_load(:active_record) do
|
13
|
+
# self.include_root_in_json = true
|
14
|
+
# end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Files in the config/locales directory are used for internationalization
|
2
|
+
# and are automatically loaded by Rails. If you want to use locales other
|
3
|
+
# than English, add the necessary files in this directory.
|
4
|
+
#
|
5
|
+
# To use the locales, use `I18n.t`:
|
6
|
+
#
|
7
|
+
# I18n.t 'hello'
|
8
|
+
#
|
9
|
+
# In views, this is aliased to just `t`:
|
10
|
+
#
|
11
|
+
# <%= t('hello') %>
|
12
|
+
#
|
13
|
+
# To use a different locale, set it with `I18n.locale`:
|
14
|
+
#
|
15
|
+
# I18n.locale = :es
|
16
|
+
#
|
17
|
+
# This would use the information in config/locales/es.yml.
|
18
|
+
#
|
19
|
+
# The following keys must be escaped otherwise they will not be retrieved by
|
20
|
+
# the default I18n backend:
|
21
|
+
#
|
22
|
+
# true, false, on, off, yes, no
|
23
|
+
#
|
24
|
+
# Instead, surround them with single quotes.
|
25
|
+
#
|
26
|
+
# en:
|
27
|
+
# 'true': 'foo'
|
28
|
+
#
|
29
|
+
# To learn more, please read the Rails Internationalization guide
|
30
|
+
# available at http://guides.rubyonrails.org/i18n.html.
|
31
|
+
|
32
|
+
en:
|
33
|
+
hello: "Hello world"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Puma can serve each request in a thread from an internal thread pool.
|
2
|
+
# The `threads` method setting takes two numbers: a minimum and maximum.
|
3
|
+
# Any libraries that use thread pools should be configured to match
|
4
|
+
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
5
|
+
# and maximum; this matches the default thread size of Active Record.
|
6
|
+
#
|
7
|
+
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
|
8
|
+
threads threads_count, threads_count
|
9
|
+
|
10
|
+
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
11
|
+
#
|
12
|
+
port ENV.fetch("PORT") { 3000 }
|
13
|
+
|
14
|
+
# Specifies the `environment` that Puma will run in.
|
15
|
+
#
|
16
|
+
environment ENV.fetch("RAILS_ENV") { "development" }
|
17
|
+
|
18
|
+
# Specifies the number of `workers` to boot in clustered mode.
|
19
|
+
# Workers are forked webserver processes. If using threads and workers together
|
20
|
+
# the concurrency of the application would be max `threads` * `workers`.
|
21
|
+
# Workers do not work on JRuby or Windows (both of which do not support
|
22
|
+
# processes).
|
23
|
+
#
|
24
|
+
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
|
25
|
+
|
26
|
+
# Use the `preload_app!` method when specifying a `workers` number.
|
27
|
+
# This directive tells Puma to first boot the application and load code
|
28
|
+
# before forking the application. This takes advantage of Copy On Write
|
29
|
+
# process behavior so workers use less memory.
|
30
|
+
#
|
31
|
+
# preload_app!
|
32
|
+
|
33
|
+
# Allow puma to be restarted by `rails restart` command.
|
34
|
+
plugin :tmp_restart
|
@@ -0,0 +1,34 @@
|
|
1
|
+
test:
|
2
|
+
service: Disk
|
3
|
+
root: <%= Rails.root.join("tmp/storage") %>
|
4
|
+
|
5
|
+
local:
|
6
|
+
service: Disk
|
7
|
+
root: <%= Rails.root.join("storage") %>
|
8
|
+
|
9
|
+
# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
|
10
|
+
# amazon:
|
11
|
+
# service: S3
|
12
|
+
# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
|
13
|
+
# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
|
14
|
+
# region: us-east-1
|
15
|
+
# bucket: your_own_bucket
|
16
|
+
|
17
|
+
# Remember not to checkin your GCS keyfile to a repository
|
18
|
+
# google:
|
19
|
+
# service: GCS
|
20
|
+
# project: your_project
|
21
|
+
# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
|
22
|
+
# bucket: your_own_bucket
|
23
|
+
|
24
|
+
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
|
25
|
+
# microsoft:
|
26
|
+
# service: AzureStorage
|
27
|
+
# storage_account_name: your_account_name
|
28
|
+
# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
|
29
|
+
# container: your_container_name
|
30
|
+
|
31
|
+
# mirror:
|
32
|
+
# service: Mirror
|
33
|
+
# primary: local
|
34
|
+
# mirrors: [ amazon, google, microsoft ]
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# This migration comes from better_record (originally 20180725160802)
|
2
|
+
class CreateBetterRecordDBFunctions < ActiveRecord::Migration[5.2]
|
3
|
+
def up
|
4
|
+
execute "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
|
5
|
+
execute "CREATE EXTENSION IF NOT EXISTS btree_gin;"
|
6
|
+
execute "CREATE EXTENSION IF NOT EXISTS pgcrypto;"
|
7
|
+
|
8
|
+
sql = ""
|
9
|
+
source = File.new(BetterRecord::Engine.root.join('db', 'postgres-audit-trigger.psql'), "r")
|
10
|
+
while (line = source.gets)
|
11
|
+
sql << line.gsub(/SELECTED_SCHEMA_NAME/, BetterRecord.db_audit_schema)
|
12
|
+
end
|
13
|
+
source.close
|
14
|
+
|
15
|
+
execute sql
|
16
|
+
|
17
|
+
execute <<-SQL
|
18
|
+
CREATE or REPLACE FUNCTION public.temp_table_exists( varchar)
|
19
|
+
RETURNS pg_catalog.bool AS
|
20
|
+
$$
|
21
|
+
BEGIN
|
22
|
+
/* check the table exist in database and is visible*/
|
23
|
+
PERFORM n.nspname, c.relname
|
24
|
+
FROM pg_catalog.pg_class c
|
25
|
+
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
26
|
+
WHERE n.nspname LIKE 'pg_temp_%' AND pg_catalog.pg_table_is_visible(c.oid)
|
27
|
+
AND relname = $1;
|
28
|
+
|
29
|
+
IF FOUND THEN
|
30
|
+
RETURN TRUE;
|
31
|
+
ELSE
|
32
|
+
RETURN FALSE;
|
33
|
+
END IF;
|
34
|
+
|
35
|
+
END;
|
36
|
+
$$
|
37
|
+
LANGUAGE 'plpgsql' VOLATILE
|
38
|
+
SQL
|
39
|
+
|
40
|
+
execute <<-SQL
|
41
|
+
CREATE OR REPLACE FUNCTION hash_password(password text)
|
42
|
+
RETURNS text AS
|
43
|
+
$BODY$
|
44
|
+
BEGIN
|
45
|
+
password = crypt(password, gen_salt('bf', 8));
|
46
|
+
|
47
|
+
RETURN password;
|
48
|
+
END;
|
49
|
+
$BODY$
|
50
|
+
|
51
|
+
LANGUAGE plpgsql;
|
52
|
+
SQL
|
53
|
+
|
54
|
+
execute <<-SQL
|
55
|
+
CREATE OR REPLACE FUNCTION validate_email(email text)
|
56
|
+
RETURNS text AS
|
57
|
+
$BODY$
|
58
|
+
BEGIN
|
59
|
+
IF email IS NOT NULL THEN
|
60
|
+
IF email !~* '\\A[^@\\s\\;]+@[^@\\s\\;]+\\.[^@\\s\\;]+\\Z' THEN
|
61
|
+
RAISE EXCEPTION 'Invalid E-mail format %', email
|
62
|
+
USING HINT = 'Please check your E-mail format.';
|
63
|
+
END IF ;
|
64
|
+
email = lower(email);
|
65
|
+
END IF ;
|
66
|
+
|
67
|
+
RETURN email;
|
68
|
+
END;
|
69
|
+
$BODY$
|
70
|
+
LANGUAGE plpgsql;
|
71
|
+
SQL
|
72
|
+
|
73
|
+
execute <<-SQL
|
74
|
+
CREATE OR REPLACE FUNCTION valid_email_trigger()
|
75
|
+
RETURNS TRIGGER AS
|
76
|
+
$BODY$
|
77
|
+
BEGIN
|
78
|
+
NEW.email = validate_email(NEW.email);
|
79
|
+
|
80
|
+
RETURN NEW;
|
81
|
+
END;
|
82
|
+
$BODY$
|
83
|
+
LANGUAGE plpgsql;
|
84
|
+
SQL
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
def down
|
89
|
+
execute 'DROP FUNCTION IF EXISTS valid_email_trigger();'
|
90
|
+
execute 'DROP FUNCTION IF EXISTS validate_email();'
|
91
|
+
execute 'DROP FUNCTION IF EXISTS temp_table_exists();'
|
92
|
+
execute "DROP FUNCTION IF EXISTS hash_password();"
|
93
|
+
execute "DROP SCHEMA IF EXISTS #{BetterRecord.db_audit_schema} CASCADE;"
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# This migration comes from better_record (originally 20180725201614)
|
2
|
+
class CreateBetterRecordTableSizes < ActiveRecord::Migration[5.2]
|
3
|
+
def change
|
4
|
+
create_table "#{BetterRecord.db_audit_schema}.table_sizes", {id: false} do |t|
|
5
|
+
t.integer :oid, limit: 8
|
6
|
+
t.string :schema
|
7
|
+
t.string :name
|
8
|
+
t.float :apx_row_count
|
9
|
+
t.integer :total_bytes, limit: 8
|
10
|
+
t.integer :idx_bytes, limit: 8
|
11
|
+
t.integer :toast_bytes, limit: 8
|
12
|
+
t.integer :tbl_bytes, limit: 8
|
13
|
+
t.text :total
|
14
|
+
t.text :idx
|
15
|
+
t.text :toast
|
16
|
+
t.text :tbl
|
17
|
+
end
|
18
|
+
|
19
|
+
reversible do |d|
|
20
|
+
d.up do
|
21
|
+
execute "ALTER TABLE #{BetterRecord.db_audit_schema}.table_sizes ADD PRIMARY KEY (oid);"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,781 @@
|
|
1
|
+
SET statement_timeout = 0;
|
2
|
+
SET lock_timeout = 0;
|
3
|
+
SET idle_in_transaction_session_timeout = 0;
|
4
|
+
SET client_encoding = 'UTF8';
|
5
|
+
SET standard_conforming_strings = on;
|
6
|
+
SELECT pg_catalog.set_config('search_path', '', false);
|
7
|
+
SET check_function_bodies = false;
|
8
|
+
SET client_min_messages = warning;
|
9
|
+
SET row_security = off;
|
10
|
+
|
11
|
+
--
|
12
|
+
-- Name: auditing; Type: SCHEMA; Schema: -; Owner: -
|
13
|
+
--
|
14
|
+
|
15
|
+
CREATE SCHEMA auditing;
|
16
|
+
|
17
|
+
|
18
|
+
--
|
19
|
+
-- Name: SCHEMA auditing; Type: COMMENT; Schema: -; Owner: -
|
20
|
+
--
|
21
|
+
|
22
|
+
COMMENT ON SCHEMA auditing IS 'Out-of-table audit/history logging tables and trigger functions';
|
23
|
+
|
24
|
+
|
25
|
+
--
|
26
|
+
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
|
27
|
+
--
|
28
|
+
|
29
|
+
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
|
30
|
+
|
31
|
+
|
32
|
+
--
|
33
|
+
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -
|
34
|
+
--
|
35
|
+
|
36
|
+
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
|
37
|
+
|
38
|
+
|
39
|
+
--
|
40
|
+
-- Name: btree_gin; Type: EXTENSION; Schema: -; Owner: -
|
41
|
+
--
|
42
|
+
|
43
|
+
CREATE EXTENSION IF NOT EXISTS btree_gin WITH SCHEMA public;
|
44
|
+
|
45
|
+
|
46
|
+
--
|
47
|
+
-- Name: EXTENSION btree_gin; Type: COMMENT; Schema: -; Owner: -
|
48
|
+
--
|
49
|
+
|
50
|
+
COMMENT ON EXTENSION btree_gin IS 'support for indexing common datatypes in GIN';
|
51
|
+
|
52
|
+
|
53
|
+
--
|
54
|
+
-- Name: hstore; Type: EXTENSION; Schema: -; Owner: -
|
55
|
+
--
|
56
|
+
|
57
|
+
CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;
|
58
|
+
|
59
|
+
|
60
|
+
--
|
61
|
+
-- Name: EXTENSION hstore; Type: COMMENT; Schema: -; Owner: -
|
62
|
+
--
|
63
|
+
|
64
|
+
COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs';
|
65
|
+
|
66
|
+
|
67
|
+
--
|
68
|
+
-- Name: pg_trgm; Type: EXTENSION; Schema: -; Owner: -
|
69
|
+
--
|
70
|
+
|
71
|
+
CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;
|
72
|
+
|
73
|
+
|
74
|
+
--
|
75
|
+
-- Name: EXTENSION pg_trgm; Type: COMMENT; Schema: -; Owner: -
|
76
|
+
--
|
77
|
+
|
78
|
+
COMMENT ON EXTENSION pg_trgm IS 'text similarity measurement and index searching based on trigrams';
|
79
|
+
|
80
|
+
|
81
|
+
--
|
82
|
+
-- Name: pgcrypto; Type: EXTENSION; Schema: -; Owner: -
|
83
|
+
--
|
84
|
+
|
85
|
+
CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public;
|
86
|
+
|
87
|
+
|
88
|
+
--
|
89
|
+
-- Name: EXTENSION pgcrypto; Type: COMMENT; Schema: -; Owner: -
|
90
|
+
--
|
91
|
+
|
92
|
+
COMMENT ON EXTENSION pgcrypto IS 'cryptographic functions';
|
93
|
+
|
94
|
+
|
95
|
+
--
|
96
|
+
-- Name: audit_table(regclass); Type: FUNCTION; Schema: auditing; Owner: -
|
97
|
+
--
|
98
|
+
|
99
|
+
CREATE FUNCTION auditing.audit_table(target_table regclass) RETURNS void
|
100
|
+
LANGUAGE sql
|
101
|
+
AS $_$
|
102
|
+
SELECT auditing.audit_table($1, BOOLEAN 't', BOOLEAN 't');
|
103
|
+
$_$;
|
104
|
+
|
105
|
+
|
106
|
+
--
|
107
|
+
-- Name: FUNCTION audit_table(target_table regclass); Type: COMMENT; Schema: auditing; Owner: -
|
108
|
+
--
|
109
|
+
|
110
|
+
COMMENT ON FUNCTION auditing.audit_table(target_table regclass) IS '
|
111
|
+
Add auditing support to the given table. Row-level changes will be logged with full client query text. No cols are ignored.
|
112
|
+
';
|
113
|
+
|
114
|
+
|
115
|
+
--
|
116
|
+
-- Name: audit_table(regclass, boolean, boolean); Type: FUNCTION; Schema: auditing; Owner: -
|
117
|
+
--
|
118
|
+
|
119
|
+
CREATE FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean) RETURNS void
|
120
|
+
LANGUAGE sql
|
121
|
+
AS $_$
|
122
|
+
SELECT auditing.audit_table($1, $2, $3, ARRAY[]::text[]);
|
123
|
+
$_$;
|
124
|
+
|
125
|
+
|
126
|
+
--
|
127
|
+
-- Name: audit_table(regclass, boolean, boolean, text[]); Type: FUNCTION; Schema: auditing; Owner: -
|
128
|
+
--
|
129
|
+
|
130
|
+
CREATE FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean, ignored_cols text[]) RETURNS void
|
131
|
+
LANGUAGE plpgsql
|
132
|
+
AS $$
|
133
|
+
DECLARE
|
134
|
+
stm_targets text = 'INSERT OR UPDATE OR DELETE OR TRUNCATE';
|
135
|
+
_q_txt text;
|
136
|
+
_pk_column_name text;
|
137
|
+
_pk_column_snip text;
|
138
|
+
_ignored_cols_snip text = '';
|
139
|
+
BEGIN
|
140
|
+
EXECUTE 'DROP TRIGGER IF EXISTS audit_trigger_row ON ' || quote_ident(target_table::TEXT);
|
141
|
+
EXECUTE 'DROP TRIGGER IF EXISTS audit_trigger_stm ON ' || quote_ident(target_table::TEXT);
|
142
|
+
|
143
|
+
IF audit_rows THEN
|
144
|
+
_pk_column_name = auditing.get_primary_key_column(target_table::TEXT);
|
145
|
+
|
146
|
+
IF _pk_column_name IS NOT NULL THEN
|
147
|
+
_pk_column_snip = ', ' || quote_literal(_pk_column_name);
|
148
|
+
ELSE
|
149
|
+
_pk_column_snip = ', NULL';
|
150
|
+
END IF;
|
151
|
+
|
152
|
+
IF array_length(ignored_cols,1) > 0 THEN
|
153
|
+
_ignored_cols_snip = ', ' || quote_literal(ignored_cols);
|
154
|
+
END IF;
|
155
|
+
_q_txt = 'CREATE TRIGGER audit_trigger_row AFTER INSERT OR UPDATE OR DELETE ON ' ||
|
156
|
+
quote_ident(target_table::TEXT) ||
|
157
|
+
' FOR EACH ROW EXECUTE PROCEDURE auditing.if_modified_func(' ||
|
158
|
+
quote_literal(audit_query_text) || _pk_column_snip || _ignored_cols_snip || ');';
|
159
|
+
RAISE NOTICE '%',_q_txt;
|
160
|
+
EXECUTE _q_txt;
|
161
|
+
stm_targets = 'TRUNCATE';
|
162
|
+
ELSE
|
163
|
+
END IF;
|
164
|
+
|
165
|
+
_q_txt = 'CREATE TRIGGER audit_trigger_stm AFTER ' || stm_targets || ' ON ' ||
|
166
|
+
target_table ||
|
167
|
+
' FOR EACH STATEMENT EXECUTE PROCEDURE auditing.if_modified_func('||
|
168
|
+
quote_literal(audit_query_text) || ');';
|
169
|
+
RAISE NOTICE '%',_q_txt;
|
170
|
+
EXECUTE _q_txt;
|
171
|
+
|
172
|
+
END;
|
173
|
+
$$;
|
174
|
+
|
175
|
+
|
176
|
+
--
|
177
|
+
-- Name: FUNCTION audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean, ignored_cols text[]); Type: COMMENT; Schema: auditing; Owner: -
|
178
|
+
--
|
179
|
+
|
180
|
+
COMMENT ON FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean, ignored_cols text[]) IS '
|
181
|
+
Add auditing support to a table.
|
182
|
+
|
183
|
+
Arguments:
|
184
|
+
target_table: Table name, schema qualified if not on search_path
|
185
|
+
audit_rows: Record each row change, or only audit at a statement level
|
186
|
+
audit_query_text: Record the text of the client query that triggered the audit event?
|
187
|
+
ignored_cols: Columns to exclude from update diffs, ignore updates that change only ignored cols.
|
188
|
+
';
|
189
|
+
|
190
|
+
|
191
|
+
--
|
192
|
+
-- Name: get_primary_key_column(text); Type: FUNCTION; Schema: auditing; Owner: -
|
193
|
+
--
|
194
|
+
|
195
|
+
CREATE FUNCTION auditing.get_primary_key_column(target_table text) RETURNS text
|
196
|
+
LANGUAGE plpgsql
|
197
|
+
AS $$
|
198
|
+
DECLARE
|
199
|
+
_pk_query_text text;
|
200
|
+
_pk_column_name text;
|
201
|
+
BEGIN
|
202
|
+
_pk_query_text = 'SELECT a.attname ' ||
|
203
|
+
'FROM pg_index i ' ||
|
204
|
+
'JOIN pg_attribute a ON a.attrelid = i.indrelid ' ||
|
205
|
+
' AND a.attnum = ANY(i.indkey) ' ||
|
206
|
+
'WHERE i.indrelid = ' || quote_literal(target_table::TEXT) || '::regclass ' ||
|
207
|
+
'AND i.indisprimary ' ||
|
208
|
+
'AND format_type(a.atttypid, a.atttypmod) = ' || quote_literal('bigint'::TEXT) ||
|
209
|
+
'LIMIT 1';
|
210
|
+
|
211
|
+
EXECUTE _pk_query_text INTO _pk_column_name;
|
212
|
+
raise notice 'Value %', _pk_column_name;
|
213
|
+
return _pk_column_name;
|
214
|
+
END;
|
215
|
+
$$;
|
216
|
+
|
217
|
+
|
218
|
+
--
|
219
|
+
-- Name: FUNCTION get_primary_key_column(target_table text); Type: COMMENT; Schema: auditing; Owner: -
|
220
|
+
--
|
221
|
+
|
222
|
+
COMMENT ON FUNCTION auditing.get_primary_key_column(target_table text) IS '
|
223
|
+
Get primary key column name if single PK and type bigint.
|
224
|
+
|
225
|
+
Arguments:
|
226
|
+
target_table: Table name, schema qualified if not on search_path
|
227
|
+
';
|
228
|
+
|
229
|
+
|
230
|
+
--
|
231
|
+
-- Name: if_modified_func(); Type: FUNCTION; Schema: auditing; Owner: -
|
232
|
+
--
|
233
|
+
|
234
|
+
CREATE FUNCTION auditing.if_modified_func() RETURNS trigger
|
235
|
+
LANGUAGE plpgsql SECURITY DEFINER
|
236
|
+
SET search_path TO pg_catalog, public
|
237
|
+
AS $_$
|
238
|
+
DECLARE
|
239
|
+
audit_row auditing.logged_actions;
|
240
|
+
include_values boolean;
|
241
|
+
log_diffs boolean;
|
242
|
+
h_old hstore;
|
243
|
+
h_new hstore;
|
244
|
+
user_row record;
|
245
|
+
excluded_cols text[] = ARRAY[]::text[];
|
246
|
+
pk_val_query text;
|
247
|
+
BEGIN
|
248
|
+
IF TG_WHEN <> 'AFTER' THEN
|
249
|
+
RAISE EXCEPTION 'auditing.if_modified_func() may only run as an AFTER trigger';
|
250
|
+
END IF;
|
251
|
+
|
252
|
+
audit_row = ROW(
|
253
|
+
nextval('auditing.logged_actions_event_id_seq'), -- event_id
|
254
|
+
TG_TABLE_SCHEMA::text, -- schema_name
|
255
|
+
TG_TABLE_NAME::text, -- table_name
|
256
|
+
TG_RELID, -- relation OID for much quicker searches
|
257
|
+
session_user::text, -- session_user_name
|
258
|
+
NULL, NULL, NULL, -- app_user_id, app_user_type, app_ip_address
|
259
|
+
current_timestamp, -- action_tstamp_tx
|
260
|
+
statement_timestamp(), -- action_tstamp_stm
|
261
|
+
clock_timestamp(), -- action_tstamp_clk
|
262
|
+
txid_current(), -- transaction ID
|
263
|
+
current_setting('application_name'), -- client application
|
264
|
+
inet_client_addr(), -- client_addr
|
265
|
+
inet_client_port(), -- client_port
|
266
|
+
current_query(), -- top-level query or queries (if multistatement) from client
|
267
|
+
substring(TG_OP,1,1), -- action
|
268
|
+
NULL, NULL, NULL, -- row_id, row_data, changed_fields
|
269
|
+
'f' -- statement_only
|
270
|
+
);
|
271
|
+
|
272
|
+
IF NOT TG_ARGV[0]::boolean IS DISTINCT FROM 'f'::boolean THEN
|
273
|
+
audit_row.client_query = NULL;
|
274
|
+
END IF;
|
275
|
+
|
276
|
+
IF ((TG_ARGV[1] IS NOT NULL) AND (TG_LEVEL = 'ROW')) THEN
|
277
|
+
pk_val_query = 'SELECT $1.' || quote_ident(TG_ARGV[1]::text);
|
278
|
+
|
279
|
+
IF (TG_OP IS DISTINCT FROM 'DELETE') THEN
|
280
|
+
EXECUTE pk_val_query INTO audit_row.row_id USING NEW;
|
281
|
+
END IF;
|
282
|
+
|
283
|
+
IF audit_row.row_id IS NULL THEN
|
284
|
+
EXECUTE pk_val_query INTO audit_row.row_id USING OLD;
|
285
|
+
END IF;
|
286
|
+
END IF;
|
287
|
+
|
288
|
+
IF TG_ARGV[2] IS NOT NULL THEN
|
289
|
+
excluded_cols = TG_ARGV[2]::text[];
|
290
|
+
END IF;
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
IF (TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW') THEN
|
295
|
+
audit_row.row_data = hstore(OLD.*) - excluded_cols;
|
296
|
+
audit_row.changed_fields = (hstore(NEW.*) - audit_row.row_data) - excluded_cols;
|
297
|
+
IF audit_row.changed_fields = hstore('') THEN
|
298
|
+
-- All changed fields are ignored. Skip this update.
|
299
|
+
RETURN NULL;
|
300
|
+
END IF;
|
301
|
+
ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
|
302
|
+
audit_row.row_data = hstore(OLD.*) - excluded_cols;
|
303
|
+
ELSIF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
|
304
|
+
audit_row.row_data = hstore(NEW.*) - excluded_cols;
|
305
|
+
ELSIF (TG_LEVEL = 'STATEMENT' AND TG_OP IN ('INSERT','UPDATE','DELETE','TRUNCATE')) THEN
|
306
|
+
audit_row.statement_only = 't';
|
307
|
+
ELSE
|
308
|
+
RAISE EXCEPTION '[auditing.if_modified_func] - Trigger func added as trigger for unhandled case: %, %',TG_OP, TG_LEVEL;
|
309
|
+
RETURN NULL;
|
310
|
+
END IF;
|
311
|
+
|
312
|
+
-- inject app_user data into audit
|
313
|
+
BEGIN
|
314
|
+
PERFORM
|
315
|
+
n.nspname, c.relname
|
316
|
+
FROM
|
317
|
+
pg_catalog.pg_class c
|
318
|
+
LEFT JOIN
|
319
|
+
pg_catalog.pg_namespace n
|
320
|
+
ON n.oid = c.relnamespace
|
321
|
+
WHERE
|
322
|
+
n.nspname like 'pg_temp_%'
|
323
|
+
AND
|
324
|
+
c.relname = '_app_user';
|
325
|
+
|
326
|
+
IF FOUND THEN
|
327
|
+
FOR user_row IN SELECT * FROM _app_user LIMIT 1 LOOP
|
328
|
+
audit_row.app_user_id = user_row.user_id;
|
329
|
+
audit_row.app_user_type = user_row.user_type;
|
330
|
+
audit_row.app_ip_address = user_row.ip_address;
|
331
|
+
END LOOP;
|
332
|
+
END IF;
|
333
|
+
END;
|
334
|
+
-- end app_user data
|
335
|
+
|
336
|
+
INSERT INTO auditing.logged_actions VALUES (audit_row.*);
|
337
|
+
RETURN NULL;
|
338
|
+
END;
|
339
|
+
$_$;
|
340
|
+
|
341
|
+
|
342
|
+
--
|
343
|
+
-- Name: FUNCTION if_modified_func(); Type: COMMENT; Schema: auditing; Owner: -
|
344
|
+
--
|
345
|
+
|
346
|
+
COMMENT ON FUNCTION auditing.if_modified_func() IS '
|
347
|
+
Track changes to a table at the statement and/or row level.
|
348
|
+
|
349
|
+
Optional parameters to trigger in CREATE TRIGGER call:
|
350
|
+
|
351
|
+
param 0: boolean, whether to log the query text. Default ''t''.
|
352
|
+
|
353
|
+
param 1: text, primary_key_column of audited table if bigint.
|
354
|
+
|
355
|
+
param 2: text[], columns to ignore in updates. Default [].
|
356
|
+
|
357
|
+
Updates to ignored cols are omitted from changed_fields.
|
358
|
+
|
359
|
+
Updates with only ignored cols changed are not inserted
|
360
|
+
into the audit log.
|
361
|
+
|
362
|
+
Almost all the processing work is still done for updates
|
363
|
+
that ignored. If you need to save the load, you need to use
|
364
|
+
WHEN clause on the trigger instead.
|
365
|
+
|
366
|
+
No warning or error is issued if ignored_cols contains columns
|
367
|
+
that do not exist in the target table. This lets you specify
|
368
|
+
a standard set of ignored columns.
|
369
|
+
|
370
|
+
There is no parameter to disable logging of values. Add this trigger as
|
371
|
+
a ''FOR EACH STATEMENT'' rather than ''FOR EACH ROW'' trigger if you do not
|
372
|
+
want to log row values.
|
373
|
+
|
374
|
+
Note that the user name logged is the login role for the session. The audit trigger
|
375
|
+
cannot obtain the active role because it is reset by the SECURITY DEFINER invocation
|
376
|
+
of the audit trigger its self.
|
377
|
+
';
|
378
|
+
|
379
|
+
|
380
|
+
--
|
381
|
+
-- Name: hash_password(text); Type: FUNCTION; Schema: public; Owner: -
|
382
|
+
--
|
383
|
+
|
384
|
+
CREATE FUNCTION public.hash_password(password text) RETURNS text
|
385
|
+
LANGUAGE plpgsql
|
386
|
+
AS $$
|
387
|
+
BEGIN
|
388
|
+
password = crypt(password, gen_salt('bf', 8));
|
389
|
+
|
390
|
+
RETURN password;
|
391
|
+
END;
|
392
|
+
$$;
|
393
|
+
|
394
|
+
|
395
|
+
--
|
396
|
+
-- Name: temp_table_exists(character varying); Type: FUNCTION; Schema: public; Owner: -
|
397
|
+
--
|
398
|
+
|
399
|
+
CREATE FUNCTION public.temp_table_exists(character varying) RETURNS boolean
|
400
|
+
LANGUAGE plpgsql
|
401
|
+
AS $_$
|
402
|
+
BEGIN
|
403
|
+
/* check the table exist in database and is visible*/
|
404
|
+
PERFORM n.nspname, c.relname
|
405
|
+
FROM pg_catalog.pg_class c
|
406
|
+
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
407
|
+
WHERE n.nspname LIKE 'pg_temp_%' AND pg_catalog.pg_table_is_visible(c.oid)
|
408
|
+
AND relname = $1;
|
409
|
+
|
410
|
+
IF FOUND THEN
|
411
|
+
RETURN TRUE;
|
412
|
+
ELSE
|
413
|
+
RETURN FALSE;
|
414
|
+
END IF;
|
415
|
+
|
416
|
+
END;
|
417
|
+
$_$;
|
418
|
+
|
419
|
+
|
420
|
+
--
|
421
|
+
-- Name: valid_email_trigger(); Type: FUNCTION; Schema: public; Owner: -
|
422
|
+
--
|
423
|
+
|
424
|
+
CREATE FUNCTION public.valid_email_trigger() RETURNS trigger
|
425
|
+
LANGUAGE plpgsql
|
426
|
+
AS $$
|
427
|
+
BEGIN
|
428
|
+
NEW.email = validate_email(NEW.email);
|
429
|
+
|
430
|
+
RETURN NEW;
|
431
|
+
END;
|
432
|
+
$$;
|
433
|
+
|
434
|
+
|
435
|
+
--
|
436
|
+
-- Name: validate_email(text); Type: FUNCTION; Schema: public; Owner: -
|
437
|
+
--
|
438
|
+
|
439
|
+
CREATE FUNCTION public.validate_email(email text) RETURNS text
|
440
|
+
LANGUAGE plpgsql
|
441
|
+
AS $$
|
442
|
+
BEGIN
|
443
|
+
IF email IS NOT NULL THEN
|
444
|
+
IF email !~* '\A[^@\s\;]+@[^@\s\;]+\.[^@\s\;]+\Z' THEN
|
445
|
+
RAISE EXCEPTION 'Invalid E-mail format %', email
|
446
|
+
USING HINT = 'Please check your E-mail format.';
|
447
|
+
END IF ;
|
448
|
+
email = lower(email);
|
449
|
+
END IF ;
|
450
|
+
|
451
|
+
RETURN email;
|
452
|
+
END;
|
453
|
+
$$;
|
454
|
+
|
455
|
+
|
456
|
+
SET default_tablespace = '';
|
457
|
+
|
458
|
+
SET default_with_oids = false;
|
459
|
+
|
460
|
+
--
|
461
|
+
-- Name: logged_actions; Type: TABLE; Schema: auditing; Owner: -
|
462
|
+
--
|
463
|
+
|
464
|
+
CREATE TABLE auditing.logged_actions (
|
465
|
+
event_id bigint NOT NULL,
|
466
|
+
schema_name text NOT NULL,
|
467
|
+
table_name text NOT NULL,
|
468
|
+
relid oid NOT NULL,
|
469
|
+
session_user_name text,
|
470
|
+
app_user_id integer,
|
471
|
+
app_user_type text,
|
472
|
+
app_ip_address inet,
|
473
|
+
action_tstamp_tx timestamp with time zone NOT NULL,
|
474
|
+
action_tstamp_stm timestamp with time zone NOT NULL,
|
475
|
+
action_tstamp_clk timestamp with time zone NOT NULL,
|
476
|
+
transaction_id bigint,
|
477
|
+
application_name text,
|
478
|
+
client_addr inet,
|
479
|
+
client_port integer,
|
480
|
+
client_query text,
|
481
|
+
action text NOT NULL,
|
482
|
+
row_id bigint,
|
483
|
+
row_data public.hstore,
|
484
|
+
changed_fields public.hstore,
|
485
|
+
statement_only boolean NOT NULL,
|
486
|
+
CONSTRAINT logged_actions_action_check CHECK ((action = ANY (ARRAY['I'::text, 'D'::text, 'U'::text, 'T'::text])))
|
487
|
+
);
|
488
|
+
|
489
|
+
|
490
|
+
--
|
491
|
+
-- Name: TABLE logged_actions; Type: COMMENT; Schema: auditing; Owner: -
|
492
|
+
--
|
493
|
+
|
494
|
+
COMMENT ON TABLE auditing.logged_actions IS 'History of auditable actions on audited tables, from auditing.if_modified_func()';
|
495
|
+
|
496
|
+
|
497
|
+
--
|
498
|
+
-- Name: COLUMN logged_actions.event_id; Type: COMMENT; Schema: auditing; Owner: -
|
499
|
+
--
|
500
|
+
|
501
|
+
COMMENT ON COLUMN auditing.logged_actions.event_id IS 'Unique identifier for each auditable event';
|
502
|
+
|
503
|
+
|
504
|
+
--
|
505
|
+
-- Name: COLUMN logged_actions.schema_name; Type: COMMENT; Schema: auditing; Owner: -
|
506
|
+
--
|
507
|
+
|
508
|
+
COMMENT ON COLUMN auditing.logged_actions.schema_name IS 'Database schema audited table for this event is in';
|
509
|
+
|
510
|
+
|
511
|
+
--
|
512
|
+
-- Name: COLUMN logged_actions.table_name; Type: COMMENT; Schema: auditing; Owner: -
|
513
|
+
--
|
514
|
+
|
515
|
+
COMMENT ON COLUMN auditing.logged_actions.table_name IS 'Non-schema-qualified table name of table event occured in';
|
516
|
+
|
517
|
+
|
518
|
+
--
|
519
|
+
-- Name: COLUMN logged_actions.relid; Type: COMMENT; Schema: auditing; Owner: -
|
520
|
+
--
|
521
|
+
|
522
|
+
COMMENT ON COLUMN auditing.logged_actions.relid IS 'Table OID. Changes with drop/create. Get with ''tablename''::regclass';
|
523
|
+
|
524
|
+
|
525
|
+
--
|
526
|
+
-- Name: COLUMN logged_actions.session_user_name; Type: COMMENT; Schema: auditing; Owner: -
|
527
|
+
--
|
528
|
+
|
529
|
+
COMMENT ON COLUMN auditing.logged_actions.session_user_name IS 'Login / session user whose statement caused the audited event';
|
530
|
+
|
531
|
+
|
532
|
+
--
|
533
|
+
-- Name: COLUMN logged_actions.app_user_id; Type: COMMENT; Schema: auditing; Owner: -
|
534
|
+
--
|
535
|
+
|
536
|
+
COMMENT ON COLUMN auditing.logged_actions.app_user_id IS 'Application-provided polymorphic user id';
|
537
|
+
|
538
|
+
|
539
|
+
--
|
540
|
+
-- Name: COLUMN logged_actions.app_user_type; Type: COMMENT; Schema: auditing; Owner: -
|
541
|
+
--
|
542
|
+
|
543
|
+
COMMENT ON COLUMN auditing.logged_actions.app_user_type IS 'Application-provided polymorphic user type';
|
544
|
+
|
545
|
+
|
546
|
+
--
|
547
|
+
-- Name: COLUMN logged_actions.app_ip_address; Type: COMMENT; Schema: auditing; Owner: -
|
548
|
+
--
|
549
|
+
|
550
|
+
COMMENT ON COLUMN auditing.logged_actions.app_ip_address IS 'Application-provided ip address of user whose statement caused the audited event';
|
551
|
+
|
552
|
+
|
553
|
+
--
|
554
|
+
-- Name: COLUMN logged_actions.action_tstamp_tx; Type: COMMENT; Schema: auditing; Owner: -
|
555
|
+
--
|
556
|
+
|
557
|
+
COMMENT ON COLUMN auditing.logged_actions.action_tstamp_tx IS 'Transaction start timestamp for tx in which audited event occurred';
|
558
|
+
|
559
|
+
|
560
|
+
--
|
561
|
+
-- Name: COLUMN logged_actions.action_tstamp_stm; Type: COMMENT; Schema: auditing; Owner: -
|
562
|
+
--
|
563
|
+
|
564
|
+
COMMENT ON COLUMN auditing.logged_actions.action_tstamp_stm IS 'Statement start timestamp for tx in which audited event occurred';
|
565
|
+
|
566
|
+
|
567
|
+
--
|
568
|
+
-- Name: COLUMN logged_actions.action_tstamp_clk; Type: COMMENT; Schema: auditing; Owner: -
|
569
|
+
--
|
570
|
+
|
571
|
+
COMMENT ON COLUMN auditing.logged_actions.action_tstamp_clk IS 'Wall clock time at which audited event''s trigger call occurred';
|
572
|
+
|
573
|
+
|
574
|
+
--
|
575
|
+
-- Name: COLUMN logged_actions.transaction_id; Type: COMMENT; Schema: auditing; Owner: -
|
576
|
+
--
|
577
|
+
|
578
|
+
COMMENT ON COLUMN auditing.logged_actions.transaction_id IS 'Identifier of transaction that made the change. May wrap, but unique paired with action_tstamp_tx.';
|
579
|
+
|
580
|
+
|
581
|
+
--
|
582
|
+
-- Name: COLUMN logged_actions.application_name; Type: COMMENT; Schema: auditing; Owner: -
|
583
|
+
--
|
584
|
+
|
585
|
+
COMMENT ON COLUMN auditing.logged_actions.application_name IS 'Application name set when this audit event occurred. Can be changed in-session by client.';
|
586
|
+
|
587
|
+
|
588
|
+
--
|
589
|
+
-- Name: COLUMN logged_actions.client_addr; Type: COMMENT; Schema: auditing; Owner: -
|
590
|
+
--
|
591
|
+
|
592
|
+
COMMENT ON COLUMN auditing.logged_actions.client_addr IS 'IP address of client that issued query. Null for unix domain socket.';
|
593
|
+
|
594
|
+
|
595
|
+
--
|
596
|
+
-- Name: COLUMN logged_actions.client_port; Type: COMMENT; Schema: auditing; Owner: -
|
597
|
+
--
|
598
|
+
|
599
|
+
COMMENT ON COLUMN auditing.logged_actions.client_port IS 'Remote peer IP port address of client that issued query. Undefined for unix socket.';
|
600
|
+
|
601
|
+
|
602
|
+
--
|
603
|
+
-- Name: COLUMN logged_actions.client_query; Type: COMMENT; Schema: auditing; Owner: -
|
604
|
+
--
|
605
|
+
|
606
|
+
COMMENT ON COLUMN auditing.logged_actions.client_query IS 'Top-level query that caused this auditable event. May be more than one statement.';
|
607
|
+
|
608
|
+
|
609
|
+
--
|
610
|
+
-- Name: COLUMN logged_actions.action; Type: COMMENT; Schema: auditing; Owner: -
|
611
|
+
--
|
612
|
+
|
613
|
+
COMMENT ON COLUMN auditing.logged_actions.action IS 'Action type; I = insert, D = delete, U = update, T = truncate';
|
614
|
+
|
615
|
+
|
616
|
+
--
|
617
|
+
-- Name: COLUMN logged_actions.row_id; Type: COMMENT; Schema: auditing; Owner: -
|
618
|
+
--
|
619
|
+
|
620
|
+
COMMENT ON COLUMN auditing.logged_actions.row_id IS 'Record primary_key. Null for statement-level trigger. Prefers NEW.id if exists';
|
621
|
+
|
622
|
+
|
623
|
+
--
|
624
|
+
-- Name: COLUMN logged_actions.row_data; Type: COMMENT; Schema: auditing; Owner: -
|
625
|
+
--
|
626
|
+
|
627
|
+
COMMENT ON COLUMN auditing.logged_actions.row_data IS 'Record value. Null for statement-level trigger. For INSERT this is the new tuple. For DELETE and UPDATE it is the old tuple.';
|
628
|
+
|
629
|
+
|
630
|
+
--
|
631
|
+
-- Name: COLUMN logged_actions.changed_fields; Type: COMMENT; Schema: auditing; Owner: -
|
632
|
+
--
|
633
|
+
|
634
|
+
COMMENT ON COLUMN auditing.logged_actions.changed_fields IS 'New values of fields changed by UPDATE. Null except for row-level UPDATE events.';
|
635
|
+
|
636
|
+
|
637
|
+
--
|
638
|
+
-- Name: COLUMN logged_actions.statement_only; Type: COMMENT; Schema: auditing; Owner: -
|
639
|
+
--
|
640
|
+
|
641
|
+
COMMENT ON COLUMN auditing.logged_actions.statement_only IS '''t'' if audit event is from an FOR EACH STATEMENT trigger, ''f'' for FOR EACH ROW';
|
642
|
+
|
643
|
+
|
644
|
+
--
|
645
|
+
-- Name: logged_actions_event_id_seq; Type: SEQUENCE; Schema: auditing; Owner: -
|
646
|
+
--
|
647
|
+
|
648
|
+
CREATE SEQUENCE auditing.logged_actions_event_id_seq
|
649
|
+
START WITH 1
|
650
|
+
INCREMENT BY 1
|
651
|
+
NO MINVALUE
|
652
|
+
NO MAXVALUE
|
653
|
+
CACHE 1;
|
654
|
+
|
655
|
+
|
656
|
+
--
|
657
|
+
-- Name: logged_actions_event_id_seq; Type: SEQUENCE OWNED BY; Schema: auditing; Owner: -
|
658
|
+
--
|
659
|
+
|
660
|
+
ALTER SEQUENCE auditing.logged_actions_event_id_seq OWNED BY auditing.logged_actions.event_id;
|
661
|
+
|
662
|
+
|
663
|
+
--
|
664
|
+
-- Name: table_sizes; Type: TABLE; Schema: auditing; Owner: -
|
665
|
+
--
|
666
|
+
|
667
|
+
CREATE TABLE auditing.table_sizes (
|
668
|
+
oid bigint NOT NULL,
|
669
|
+
schema character varying,
|
670
|
+
name character varying,
|
671
|
+
apx_row_count double precision,
|
672
|
+
total_bytes bigint,
|
673
|
+
idx_bytes bigint,
|
674
|
+
toast_bytes bigint,
|
675
|
+
tbl_bytes bigint,
|
676
|
+
total text,
|
677
|
+
idx text,
|
678
|
+
toast text,
|
679
|
+
tbl text
|
680
|
+
);
|
681
|
+
|
682
|
+
|
683
|
+
--
|
684
|
+
-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -
|
685
|
+
--
|
686
|
+
|
687
|
+
CREATE TABLE public.ar_internal_metadata (
|
688
|
+
key character varying NOT NULL,
|
689
|
+
value character varying,
|
690
|
+
created_at timestamp without time zone NOT NULL,
|
691
|
+
updated_at timestamp without time zone NOT NULL
|
692
|
+
);
|
693
|
+
|
694
|
+
|
695
|
+
--
|
696
|
+
-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -
|
697
|
+
--
|
698
|
+
|
699
|
+
CREATE TABLE public.schema_migrations (
|
700
|
+
version character varying NOT NULL
|
701
|
+
);
|
702
|
+
|
703
|
+
|
704
|
+
--
|
705
|
+
-- Name: logged_actions event_id; Type: DEFAULT; Schema: auditing; Owner: -
|
706
|
+
--
|
707
|
+
|
708
|
+
ALTER TABLE ONLY auditing.logged_actions ALTER COLUMN event_id SET DEFAULT nextval('auditing.logged_actions_event_id_seq'::regclass);
|
709
|
+
|
710
|
+
|
711
|
+
--
|
712
|
+
-- Name: logged_actions logged_actions_pkey; Type: CONSTRAINT; Schema: auditing; Owner: -
|
713
|
+
--
|
714
|
+
|
715
|
+
ALTER TABLE ONLY auditing.logged_actions
|
716
|
+
ADD CONSTRAINT logged_actions_pkey PRIMARY KEY (event_id);
|
717
|
+
|
718
|
+
|
719
|
+
--
|
720
|
+
-- Name: table_sizes table_sizes_pkey; Type: CONSTRAINT; Schema: auditing; Owner: -
|
721
|
+
--
|
722
|
+
|
723
|
+
ALTER TABLE ONLY auditing.table_sizes
|
724
|
+
ADD CONSTRAINT table_sizes_pkey PRIMARY KEY (oid);
|
725
|
+
|
726
|
+
|
727
|
+
--
|
728
|
+
-- Name: ar_internal_metadata ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
729
|
+
--
|
730
|
+
|
731
|
+
ALTER TABLE ONLY public.ar_internal_metadata
|
732
|
+
ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key);
|
733
|
+
|
734
|
+
|
735
|
+
--
|
736
|
+
-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
737
|
+
--
|
738
|
+
|
739
|
+
ALTER TABLE ONLY public.schema_migrations
|
740
|
+
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);
|
741
|
+
|
742
|
+
|
743
|
+
--
|
744
|
+
-- Name: logged_actions_action_idx; Type: INDEX; Schema: auditing; Owner: -
|
745
|
+
--
|
746
|
+
|
747
|
+
CREATE INDEX logged_actions_action_idx ON auditing.logged_actions USING btree (action);
|
748
|
+
|
749
|
+
|
750
|
+
--
|
751
|
+
-- Name: logged_actions_action_tstamp_tx_stm_idx; Type: INDEX; Schema: auditing; Owner: -
|
752
|
+
--
|
753
|
+
|
754
|
+
CREATE INDEX logged_actions_action_tstamp_tx_stm_idx ON auditing.logged_actions USING btree (action_tstamp_stm);
|
755
|
+
|
756
|
+
|
757
|
+
--
|
758
|
+
-- Name: logged_actions_relid_idx; Type: INDEX; Schema: auditing; Owner: -
|
759
|
+
--
|
760
|
+
|
761
|
+
CREATE INDEX logged_actions_relid_idx ON auditing.logged_actions USING btree (relid);
|
762
|
+
|
763
|
+
|
764
|
+
--
|
765
|
+
-- Name: logged_actions_row_id_idx; Type: INDEX; Schema: auditing; Owner: -
|
766
|
+
--
|
767
|
+
|
768
|
+
CREATE INDEX logged_actions_row_id_idx ON auditing.logged_actions USING btree (row_id);
|
769
|
+
|
770
|
+
|
771
|
+
--
|
772
|
+
-- PostgreSQL database dump complete
|
773
|
+
--
|
774
|
+
|
775
|
+
SET search_path TO "$user", public;
|
776
|
+
|
777
|
+
INSERT INTO "schema_migrations" (version) VALUES
|
778
|
+
('20180725160802'),
|
779
|
+
('20180725201614');
|
780
|
+
|
781
|
+
|