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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +12 -18
  3. data/app/models/better_record/table_size.rb +30 -28
  4. data/config/initializers/{money_type.rb → active_record/money_type.rb} +0 -0
  5. data/config/initializers/{boolean.rb → core_ext/boolean.rb} +0 -0
  6. data/config/initializers/core_ext/date.rb +9 -0
  7. data/config/initializers/{integer.rb → core_ext/integer.rb} +0 -0
  8. data/config/initializers/dkim.rb +7 -0
  9. data/config/initializers/redis_store.rb +24 -0
  10. data/lib/better_record.rb +6 -4
  11. data/lib/better_record/engine.rb +7 -0
  12. data/lib/better_record/fake_redis.rb +94 -0
  13. data/lib/better_record/version.rb +1 -1
  14. data/lib/tasks/spec/attributes.rake +7 -1
  15. data/spec/dummy/Rakefile +6 -0
  16. data/spec/dummy/app/assets/config/manifest.js +4 -0
  17. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  18. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  19. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  20. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  21. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  22. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  23. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  24. data/spec/dummy/app/jobs/application_job.rb +2 -0
  25. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  26. data/spec/dummy/app/models/application_record.rb +3 -0
  27. data/spec/dummy/app/models/test_audit.rb +2 -0
  28. data/spec/dummy/app/models/test_custom_audit.rb +2 -0
  29. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  30. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  31. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  32. data/spec/dummy/bin/bundle +3 -0
  33. data/spec/dummy/bin/rails +4 -0
  34. data/spec/dummy/bin/rake +4 -0
  35. data/spec/dummy/bin/setup +36 -0
  36. data/spec/dummy/bin/update +31 -0
  37. data/spec/dummy/bin/yarn +11 -0
  38. data/spec/dummy/config.ru +5 -0
  39. data/spec/dummy/config/application.rb +19 -0
  40. data/spec/dummy/config/boot.rb +5 -0
  41. data/spec/dummy/config/cable.yml +10 -0
  42. data/spec/dummy/config/database.yml +25 -0
  43. data/spec/dummy/config/environment.rb +5 -0
  44. data/spec/dummy/config/environments/development.rb +61 -0
  45. data/spec/dummy/config/environments/production.rb +94 -0
  46. data/spec/dummy/config/environments/test.rb +46 -0
  47. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  48. data/spec/dummy/config/initializers/assets.rb +14 -0
  49. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  50. data/spec/dummy/config/initializers/better_record.rb +42 -0
  51. data/{config → spec/dummy/config}/initializers/content_security_policy.rb +0 -0
  52. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  53. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  54. data/spec/dummy/config/initializers/inflections.rb +16 -0
  55. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  56. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  57. data/spec/dummy/config/locales/en.yml +33 -0
  58. data/spec/dummy/config/puma.rb +34 -0
  59. data/spec/dummy/config/routes.rb +3 -0
  60. data/spec/dummy/config/spring.rb +6 -0
  61. data/spec/dummy/config/storage.yml +34 -0
  62. data/spec/dummy/db/migrate/20180725233004_create_test_audits.rb +11 -0
  63. data/spec/dummy/db/migrate/20180725233007_create_test_custom_audits.rb +12 -0
  64. data/spec/dummy/db/migrate/20180725235254_create_better_record_db_functions.better_record.rb +95 -0
  65. data/spec/dummy/db/migrate/20180725235255_create_better_record_table_sizes.better_record.rb +25 -0
  66. data/spec/dummy/db/structure.sql +781 -0
  67. data/spec/dummy/lib/templates/active_record/model/model.rb +31 -0
  68. data/spec/dummy/lib/templates/rspec/model/model_spec.rb +17 -0
  69. data/spec/dummy/log/development.log +2495 -0
  70. data/spec/dummy/log/test.log +197 -0
  71. data/spec/dummy/package.json +5 -0
  72. data/spec/dummy/public/404.html +67 -0
  73. data/spec/dummy/public/422.html +67 -0
  74. data/spec/dummy/public/500.html +66 -0
  75. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  76. data/spec/dummy/public/apple-touch-icon.png +0 -0
  77. data/spec/dummy/public/favicon.ico +0 -0
  78. data/spec/dummy/spec/factories/test_audits.rb +7 -0
  79. data/spec/dummy/spec/factories/test_custom_audits.rb +8 -0
  80. data/spec/dummy/spec/models/test_audit_spec.rb +5 -0
  81. data/spec/dummy/spec/models/test_custom_audit_spec.rb +5 -0
  82. data/spec/factories/better_record_table_sizes.rb +16 -0
  83. data/spec/factories/test_audits.rb +7 -0
  84. data/spec/factories/test_custom_audits.rb +8 -0
  85. data/spec/lib/generators/better_record/install_generator_test.rb +16 -0
  86. data/spec/method_helper.rb +7 -0
  87. data/spec/method_helper/functions.rb +9 -0
  88. data/spec/method_helper/functions/boolean_column.rb +52 -0
  89. data/spec/method_helper/functions/has_valid_factory.rb +20 -0
  90. data/spec/method_helper/functions/optional_column.rb +17 -0
  91. data/spec/method_helper/functions/required_column.rb +35 -0
  92. data/spec/models/better_record/logged_action_spec.rb +35 -0
  93. data/spec/models/better_record/table_size_spec.rb +26 -0
  94. data/spec/models/test_audit_spec.rb +5 -0
  95. data/spec/models/test_custom_audit_spec.rb +5 -0
  96. data/spec/rails_helper.rb +36 -0
  97. data/spec/tmp/testes +0 -0
  98. 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
@@ -0,0 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Specify a serializer for the signed and encrypted cookie jars.
4
+ # Valid options are :json, :marshal, and :hybrid.
5
+ Rails.application.config.action_dispatch.cookies_serializer = :json
@@ -0,0 +1,4 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Configure sensitive parameters which will be filtered from the log file.
4
+ Rails.application.config.filter_parameters += [:password]
@@ -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,4 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new mime types for use in respond_to blocks:
4
+ # Mime::Type.register "text/richtext", :rtf
@@ -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,3 @@
1
+ Rails.application.routes.draw do
2
+ mount BetterRecord::Engine => "/better_record"
3
+ end
@@ -0,0 +1,6 @@
1
+ %w[
2
+ .ruby-version
3
+ .rbenv-vars
4
+ tmp/restart.txt
5
+ tmp/caching-dev.txt
6
+ ].each { |path| Spring.watch(path) }
@@ -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,11 @@
1
+ class CreateTestAudits < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :test_audits do |t|
4
+ t.text :test_text
5
+ t.date :test_date
6
+ t.datetime :test_time
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class CreateTestCustomAudits < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :test_custom_audits do |t|
4
+ t.text :test_text
5
+ t.date :test_date
6
+ t.datetime :test_time
7
+ t.text :test_skipped_column
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -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
+