better_record 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/{spec/dummy/app/assets/javascripts → app/assets/javascripts/better_record}/application.js +0 -0
  3. data/app/assets/javascripts/better_record/table_sizes.js +2 -0
  4. data/{spec/dummy/app/assets/stylesheets → app/assets/stylesheets/better_record}/application.css +0 -0
  5. data/app/assets/stylesheets/better_record/table_sizes.css +4 -0
  6. data/app/views/better_record/table_sizes/index.html.erb +34 -0
  7. data/app/views/better_record/table_sizes/show.html.erb +28 -0
  8. data/app/views/layouts/better_record/application.html.erb +16 -0
  9. data/lib/better_record/version.rb +1 -1
  10. data/lib/generators/better_record/setup/USAGE +15 -0
  11. data/lib/generators/better_record/setup/setup_generator.rb +91 -0
  12. data/lib/generators/better_record/setup/templates/gitattributes +20 -0
  13. data/lib/generators/better_record/setup/templates/gitignore +44 -0
  14. data/{spec/dummy/config/initializers/better_record.rb → lib/generators/better_record/setup/templates/initializer.rb} +0 -0
  15. data/lib/generators/better_record/setup/templates/irbrc +7 -0
  16. data/lib/generators/better_record/setup/templates/jsbeautifyrc +18 -0
  17. data/lib/generators/better_record/setup/templates/pryrc +42 -0
  18. data/lib/generators/better_record/setup/templates/rspec +3 -0
  19. data/lib/generators/better_record/setup/templates/ruby-version +1 -0
  20. data/{spec/dummy/lib → lib}/templates/active_record/model/model.rb +0 -0
  21. data/lib/templates/migration/templates/create_table_migration.rb +19 -0
  22. data/{spec/dummy/lib → lib}/templates/rspec/model/model_spec.rb +0 -0
  23. metadata +22 -168
  24. data/spec/dummy/Rakefile +0 -6
  25. data/spec/dummy/app/assets/config/manifest.js +0 -4
  26. data/spec/dummy/app/assets/javascripts/cable.js +0 -13
  27. data/spec/dummy/app/channels/application_cable/channel.rb +0 -4
  28. data/spec/dummy/app/channels/application_cable/connection.rb +0 -4
  29. data/spec/dummy/app/controllers/application_controller.rb +0 -2
  30. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  31. data/spec/dummy/app/jobs/application_job.rb +0 -2
  32. data/spec/dummy/app/mailers/application_mailer.rb +0 -4
  33. data/spec/dummy/app/models/application_record.rb +0 -3
  34. data/spec/dummy/app/models/test_audit.rb +0 -2
  35. data/spec/dummy/app/models/test_custom_audit.rb +0 -2
  36. data/spec/dummy/app/views/layouts/application.html.erb +0 -15
  37. data/spec/dummy/app/views/layouts/mailer.html.erb +0 -13
  38. data/spec/dummy/app/views/layouts/mailer.text.erb +0 -1
  39. data/spec/dummy/bin/bundle +0 -3
  40. data/spec/dummy/bin/rails +0 -4
  41. data/spec/dummy/bin/rake +0 -4
  42. data/spec/dummy/bin/setup +0 -36
  43. data/spec/dummy/bin/update +0 -31
  44. data/spec/dummy/bin/yarn +0 -11
  45. data/spec/dummy/config.ru +0 -5
  46. data/spec/dummy/config/application.rb +0 -19
  47. data/spec/dummy/config/boot.rb +0 -5
  48. data/spec/dummy/config/cable.yml +0 -10
  49. data/spec/dummy/config/database.yml +0 -25
  50. data/spec/dummy/config/environment.rb +0 -5
  51. data/spec/dummy/config/environments/development.rb +0 -61
  52. data/spec/dummy/config/environments/production.rb +0 -94
  53. data/spec/dummy/config/environments/test.rb +0 -46
  54. data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -8
  55. data/spec/dummy/config/initializers/assets.rb +0 -14
  56. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  57. data/spec/dummy/config/initializers/content_security_policy.rb +0 -25
  58. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -5
  59. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  60. data/spec/dummy/config/initializers/inflections.rb +0 -16
  61. data/spec/dummy/config/initializers/mime_types.rb +0 -4
  62. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  63. data/spec/dummy/config/locales/en.yml +0 -33
  64. data/spec/dummy/config/puma.rb +0 -34
  65. data/spec/dummy/config/routes.rb +0 -3
  66. data/spec/dummy/config/spring.rb +0 -6
  67. data/spec/dummy/config/storage.yml +0 -34
  68. data/spec/dummy/db/migrate/20180725233004_create_test_audits.rb +0 -11
  69. data/spec/dummy/db/migrate/20180725233007_create_test_custom_audits.rb +0 -12
  70. data/spec/dummy/db/migrate/20180725235254_create_better_record_db_functions.better_record.rb +0 -95
  71. data/spec/dummy/db/migrate/20180725235255_create_better_record_table_sizes.better_record.rb +0 -25
  72. data/spec/dummy/db/structure.sql +0 -781
  73. data/spec/dummy/log/development.log +0 -2495
  74. data/spec/dummy/log/test.log +0 -197
  75. data/spec/dummy/package.json +0 -5
  76. data/spec/dummy/public/404.html +0 -67
  77. data/spec/dummy/public/422.html +0 -67
  78. data/spec/dummy/public/500.html +0 -66
  79. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  80. data/spec/dummy/public/apple-touch-icon.png +0 -0
  81. data/spec/dummy/public/favicon.ico +0 -0
  82. data/spec/dummy/spec/factories/test_audits.rb +0 -7
  83. data/spec/dummy/spec/factories/test_custom_audits.rb +0 -8
  84. data/spec/dummy/spec/models/test_audit_spec.rb +0 -5
  85. data/spec/dummy/spec/models/test_custom_audit_spec.rb +0 -5
  86. data/spec/factories/better_record_table_sizes.rb +0 -16
  87. data/spec/factories/test_audits.rb +0 -7
  88. data/spec/factories/test_custom_audits.rb +0 -8
  89. data/spec/lib/generators/better_record/install_generator_test.rb +0 -16
  90. data/spec/method_helper.rb +0 -7
  91. data/spec/method_helper/functions.rb +0 -9
  92. data/spec/method_helper/functions/boolean_column.rb +0 -52
  93. data/spec/method_helper/functions/has_valid_factory.rb +0 -20
  94. data/spec/method_helper/functions/optional_column.rb +0 -17
  95. data/spec/method_helper/functions/required_column.rb +0 -35
  96. data/spec/models/better_record/logged_action_spec.rb +0 -35
  97. data/spec/models/better_record/table_size_spec.rb +0 -26
  98. data/spec/models/test_audit_spec.rb +0 -5
  99. data/spec/models/test_custom_audit_spec.rb +0 -5
  100. data/spec/rails_helper.rb +0 -36
  101. data/spec/tmp/testes +0 -0
@@ -1,2495 +0,0 @@
1
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2
- ↳ bin/rails:14
3
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
4
- ↳ bin/rails:14
5
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
6
- ↳ bin/rails:14
7
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
8
- ↳ bin/rails:14
9
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
10
- ↳ bin/rails:14
11
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
12
- ↳ bin/rails:14
13
-  (114.4ms) DROP DATABASE IF EXISTS "better_record_test"
14
- ↳ bin/rails:14
15
-  (236.9ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
16
- ↳ bin/rails:14
17
-  (0.1ms) SELECT pg_try_advisory_lock(3614663923613387715)
18
- ↳ bin/rails:14
19
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
20
- ↳ bin/rails:14
21
- Migrating to CreateBetterRecordDBFunctions (20180725160802)
22
-  (0.1ms) BEGIN
23
- ↳ bin/rails:14
24
-  (0.1ms) CREATE EXTENSION IF NOT EXISTS pg_trgm;
25
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:3
26
-  (0.1ms) CREATE EXTENSION IF NOT EXISTS btree_gin;
27
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:4
28
-  (0.1ms) CREATE EXTENSION IF NOT EXISTS pgcrypto;
29
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:5
30
-  (8.7ms) -- An audit history is important on most tables. Provide an audit trigger that logs to
31
- -- a dedicated audit table for the major relations.
32
- --
33
- -- This file should be generic and not depend on application roles or structures,
34
- -- as it's being listed here:
35
- --
36
- -- https://wiki.postgresql.org/wiki/Audit_trigger_91plus
37
- --
38
- -- This trigger was originally based on
39
- -- http://wiki.postgresql.org/wiki/Audit_trigger
40
- -- but has been completely rewritten.
41
- --
42
- -- Should really be converted into a relocatable EXTENSION, with control and upgrade files.
43
-
44
- CREATE EXTENSION IF NOT EXISTS hstore;
45
-
46
- CREATE SCHEMA auditing;
47
- REVOKE ALL ON SCHEMA auditing FROM public;
48
-
49
- COMMENT ON SCHEMA auditing IS 'Out-of-table audit/history logging tables and trigger functions';
50
-
51
- --
52
- -- Audited data. Lots of information is available, it's just a matter of how much
53
- -- you really want to record. See:
54
- --
55
- -- http://www.postgresql.org/docs/9.1/static/functions-info.html
56
- --
57
- -- Remember, every column you add takes up more audit table space and slows audit
58
- -- inserts.
59
- --
60
- -- Every index you add has a big impact too, so avoid adding indexes to the
61
- -- audit table unless you REALLY need them. The hstore GIST indexes are
62
- -- particularly expensive.
63
- --
64
- -- It is sometimes worth copying the audit table, or a coarse subset of it that
65
- -- you're interested in, into a temporary table where you CREATE any useful
66
- -- indexes and do your analysis.
67
- --
68
- CREATE TABLE auditing.logged_actions (
69
- event_id bigserial primary key,
70
- schema_name text not null,
71
- table_name text not null,
72
- relid oid not null,
73
- session_user_name text,
74
- app_user_id integer,
75
- app_user_type text,
76
- app_ip_address inet,
77
- action_tstamp_tx TIMESTAMP WITH TIME ZONE NOT NULL,
78
- action_tstamp_stm TIMESTAMP WITH TIME ZONE NOT NULL,
79
- action_tstamp_clk TIMESTAMP WITH TIME ZONE NOT NULL,
80
- transaction_id bigint,
81
- application_name text,
82
- client_addr inet,
83
- client_port integer,
84
- client_query text,
85
- action TEXT NOT NULL CHECK (action IN ('I','D','U', 'T')),
86
- row_id bigint,
87
- row_data hstore,
88
- changed_fields hstore,
89
- statement_only boolean not null
90
- );
91
-
92
- REVOKE ALL ON auditing.logged_actions FROM public;
93
-
94
- COMMENT ON TABLE auditing.logged_actions IS 'History of auditable actions on audited tables, from auditing.if_modified_func()';
95
- COMMENT ON COLUMN auditing.logged_actions.event_id IS 'Unique identifier for each auditable event';
96
- COMMENT ON COLUMN auditing.logged_actions.schema_name IS 'Database schema audited table for this event is in';
97
- COMMENT ON COLUMN auditing.logged_actions.table_name IS 'Non-schema-qualified table name of table event occured in';
98
- COMMENT ON COLUMN auditing.logged_actions.relid IS 'Table OID. Changes with drop/create. Get with ''tablename''::regclass';
99
- COMMENT ON COLUMN auditing.logged_actions.session_user_name IS 'Login / session user whose statement caused the audited event';
100
- COMMENT ON COLUMN auditing.logged_actions.app_user_id IS 'Application-provided polymorphic user id';
101
- COMMENT ON COLUMN auditing.logged_actions.app_user_type IS 'Application-provided polymorphic user type';
102
- COMMENT ON COLUMN auditing.logged_actions.app_ip_address IS 'Application-provided ip address of user whose statement caused the audited event';
103
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_tx IS 'Transaction start timestamp for tx in which audited event occurred';
104
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_stm IS 'Statement start timestamp for tx in which audited event occurred';
105
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_clk IS 'Wall clock time at which audited event''s trigger call occurred';
106
- 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.';
107
- COMMENT ON COLUMN auditing.logged_actions.client_addr IS 'IP address of client that issued query. Null for unix domain socket.';
108
- COMMENT ON COLUMN auditing.logged_actions.client_port IS 'Remote peer IP port address of client that issued query. Undefined for unix socket.';
109
- COMMENT ON COLUMN auditing.logged_actions.client_query IS 'Top-level query that caused this auditable event. May be more than one statement.';
110
- COMMENT ON COLUMN auditing.logged_actions.application_name IS 'Application name set when this audit event occurred. Can be changed in-session by client.';
111
- COMMENT ON COLUMN auditing.logged_actions.action IS 'Action type; I = insert, D = delete, U = update, T = truncate';
112
- COMMENT ON COLUMN auditing.logged_actions.row_id IS 'Record primary_key. Null for statement-level trigger. Prefers NEW.id if exists';
113
- 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.';
114
- COMMENT ON COLUMN auditing.logged_actions.changed_fields IS 'New values of fields changed by UPDATE. Null except for row-level UPDATE events.';
115
- 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';
116
-
117
- CREATE INDEX logged_actions_relid_idx ON auditing.logged_actions(relid);
118
- CREATE INDEX logged_actions_action_tstamp_tx_stm_idx ON auditing.logged_actions(action_tstamp_stm);
119
- CREATE INDEX logged_actions_action_idx ON auditing.logged_actions(action);
120
- CREATE INDEX logged_actions_row_id_idx ON auditing.logged_actions(row_id);
121
-
122
- CREATE OR REPLACE FUNCTION auditing.if_modified_func()
123
- RETURNS TRIGGER AS
124
- $$
125
- DECLARE
126
- audit_row auditing.logged_actions;
127
- include_values boolean;
128
- log_diffs boolean;
129
- h_old hstore;
130
- h_new hstore;
131
- user_row record;
132
- excluded_cols text[] = ARRAY[]::text[];
133
- pk_val_query text;
134
- BEGIN
135
- IF TG_WHEN <> 'AFTER' THEN
136
- RAISE EXCEPTION 'auditing.if_modified_func() may only run as an AFTER trigger';
137
- END IF;
138
-
139
- audit_row = ROW(
140
- nextval('auditing.logged_actions_event_id_seq'), -- event_id
141
- TG_TABLE_SCHEMA::text, -- schema_name
142
- TG_TABLE_NAME::text, -- table_name
143
- TG_RELID, -- relation OID for much quicker searches
144
- session_user::text, -- session_user_name
145
- NULL, NULL, NULL, -- app_user_id, app_user_type, app_ip_address
146
- current_timestamp, -- action_tstamp_tx
147
- statement_timestamp(), -- action_tstamp_stm
148
- clock_timestamp(), -- action_tstamp_clk
149
- txid_current(), -- transaction ID
150
- current_setting('application_name'), -- client application
151
- inet_client_addr(), -- client_addr
152
- inet_client_port(), -- client_port
153
- current_query(), -- top-level query or queries (if multistatement) from client
154
- substring(TG_OP,1,1), -- action
155
- NULL, NULL, NULL, -- row_id, row_data, changed_fields
156
- 'f' -- statement_only
157
- );
158
-
159
- IF NOT TG_ARGV[0]::boolean IS DISTINCT FROM 'f'::boolean THEN
160
- audit_row.client_query = NULL;
161
- END IF;
162
-
163
- IF ((TG_ARGV[1] IS NOT NULL) AND (TG_LEVEL = 'ROW')) THEN
164
- pk_val_query = 'SELECT $1.' || quote_ident(TG_ARGV[1]::text);
165
-
166
- IF (TG_OP IS DISTINCT FROM 'DELETE') THEN
167
- EXECUTE pk_val_query INTO audit_row.row_id USING NEW;
168
- END IF;
169
-
170
- IF audit_row.row_id IS NULL THEN
171
- EXECUTE pk_val_query INTO audit_row.row_id USING OLD;
172
- END IF;
173
- END IF;
174
-
175
- IF TG_ARGV[2] IS NOT NULL THEN
176
- excluded_cols = TG_ARGV[2]::text[];
177
- END IF;
178
-
179
-
180
-
181
- IF (TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW') THEN
182
- audit_row.row_data = hstore(OLD.*) - excluded_cols;
183
- audit_row.changed_fields = (hstore(NEW.*) - audit_row.row_data) - excluded_cols;
184
- IF audit_row.changed_fields = hstore('') THEN
185
- -- All changed fields are ignored. Skip this update.
186
- RETURN NULL;
187
- END IF;
188
- ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
189
- audit_row.row_data = hstore(OLD.*) - excluded_cols;
190
- ELSIF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
191
- audit_row.row_data = hstore(NEW.*) - excluded_cols;
192
- ELSIF (TG_LEVEL = 'STATEMENT' AND TG_OP IN ('INSERT','UPDATE','DELETE','TRUNCATE')) THEN
193
- audit_row.statement_only = 't';
194
- ELSE
195
- RAISE EXCEPTION '[auditing.if_modified_func] - Trigger func added as trigger for unhandled case: %, %',TG_OP, TG_LEVEL;
196
- RETURN NULL;
197
- END IF;
198
-
199
- -- inject app_user data into audit
200
- BEGIN
201
- PERFORM
202
- n.nspname, c.relname
203
- FROM
204
- pg_catalog.pg_class c
205
- LEFT JOIN
206
- pg_catalog.pg_namespace n
207
- ON n.oid = c.relnamespace
208
- WHERE
209
- n.nspname like 'pg_temp_%'
210
- AND
211
- c.relname = '_app_user';
212
-
213
- IF FOUND THEN
214
- FOR user_row IN SELECT * FROM _app_user LIMIT 1 LOOP
215
- audit_row.app_user_id = user_row.user_id;
216
- audit_row.app_user_type = user_row.user_type;
217
- audit_row.app_ip_address = user_row.ip_address;
218
- END LOOP;
219
- END IF;
220
- END;
221
- -- end app_user data
222
-
223
- INSERT INTO auditing.logged_actions VALUES (audit_row.*);
224
- RETURN NULL;
225
- END;
226
- $$
227
- LANGUAGE plpgsql
228
- SECURITY DEFINER
229
- SET search_path = pg_catalog, public;
230
-
231
-
232
- COMMENT ON FUNCTION auditing.if_modified_func() IS
233
- $$
234
- Track changes to a table at the statement and/or row level.
235
-
236
- Optional parameters to trigger in CREATE TRIGGER call:
237
-
238
- param 0: boolean, whether to log the query text. Default 't'.
239
-
240
- param 1: text, primary_key_column of audited table if bigint.
241
-
242
- param 2: text[], columns to ignore in updates. Default [].
243
-
244
- Updates to ignored cols are omitted from changed_fields.
245
-
246
- Updates with only ignored cols changed are not inserted
247
- into the audit log.
248
-
249
- Almost all the processing work is still done for updates
250
- that ignored. If you need to save the load, you need to use
251
- WHEN clause on the trigger instead.
252
-
253
- No warning or error is issued if ignored_cols contains columns
254
- that do not exist in the target table. This lets you specify
255
- a standard set of ignored columns.
256
-
257
- There is no parameter to disable logging of values. Add this trigger as
258
- a 'FOR EACH STATEMENT' rather than 'FOR EACH ROW' trigger if you do not
259
- want to log row values.
260
-
261
- Note that the user name logged is the login role for the session. The audit trigger
262
- cannot obtain the active role because it is reset by the SECURITY DEFINER invocation
263
- of the audit trigger its self.
264
- $$;
265
-
266
-
267
- CREATE OR REPLACE FUNCTION auditing.get_primary_key_column(target_table text)
268
- RETURNS text AS
269
- $$
270
- DECLARE
271
- _pk_query_text text;
272
- _pk_column_name text;
273
- BEGIN
274
- _pk_query_text = 'SELECT a.attname ' ||
275
- 'FROM pg_index i ' ||
276
- 'JOIN pg_attribute a ON a.attrelid = i.indrelid ' ||
277
- ' AND a.attnum = ANY(i.indkey) ' ||
278
- 'WHERE i.indrelid = ' || quote_literal(target_table::TEXT) || '::regclass ' ||
279
- 'AND i.indisprimary ' ||
280
- 'AND format_type(a.atttypid, a.atttypmod) = ' || quote_literal('bigint'::TEXT) ||
281
- 'LIMIT 1';
282
-
283
- EXECUTE _pk_query_text INTO _pk_column_name;
284
- raise notice 'Value %', _pk_column_name;
285
- return _pk_column_name;
286
- END;
287
- $$
288
- LANGUAGE plpgsql;
289
-
290
- COMMENT ON FUNCTION auditing.get_primary_key_column(text) IS
291
- $$
292
- Get primary key column name if single PK and type bigint.
293
-
294
- Arguments:
295
- target_table: Table name, schema qualified if not on search_path
296
- $$;
297
-
298
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean, ignored_cols text[])
299
- RETURNS void AS
300
- $$
301
- DECLARE
302
- stm_targets text = 'INSERT OR UPDATE OR DELETE OR TRUNCATE';
303
- _q_txt text;
304
- _pk_column_name text;
305
- _pk_column_snip text;
306
- _ignored_cols_snip text = '';
307
- BEGIN
308
- EXECUTE 'DROP TRIGGER IF EXISTS audit_trigger_row ON ' || quote_ident(target_table::TEXT);
309
- EXECUTE 'DROP TRIGGER IF EXISTS audit_trigger_stm ON ' || quote_ident(target_table::TEXT);
310
-
311
- IF audit_rows THEN
312
- _pk_column_name = auditing.get_primary_key_column(target_table::TEXT);
313
-
314
- IF _pk_column_name IS NOT NULL THEN
315
- _pk_column_snip = ', ' || quote_literal(_pk_column_name);
316
- ELSE
317
- _pk_column_snip = ', NULL';
318
- END IF;
319
-
320
- IF array_length(ignored_cols,1) > 0 THEN
321
- _ignored_cols_snip = ', ' || quote_literal(ignored_cols);
322
- END IF;
323
- _q_txt = 'CREATE TRIGGER audit_trigger_row AFTER INSERT OR UPDATE OR DELETE ON ' ||
324
- quote_ident(target_table::TEXT) ||
325
- ' FOR EACH ROW EXECUTE PROCEDURE auditing.if_modified_func(' ||
326
- quote_literal(audit_query_text) || _pk_column_snip || _ignored_cols_snip || ');';
327
- RAISE NOTICE '%',_q_txt;
328
- EXECUTE _q_txt;
329
- stm_targets = 'TRUNCATE';
330
- ELSE
331
- END IF;
332
-
333
- _q_txt = 'CREATE TRIGGER audit_trigger_stm AFTER ' || stm_targets || ' ON ' ||
334
- target_table ||
335
- ' FOR EACH STATEMENT EXECUTE PROCEDURE auditing.if_modified_func('||
336
- quote_literal(audit_query_text) || ');';
337
- RAISE NOTICE '%',_q_txt;
338
- EXECUTE _q_txt;
339
-
340
- END;
341
- $$
342
- LANGUAGE plpgsql;
343
-
344
- COMMENT ON FUNCTION auditing.audit_table(regclass, boolean, boolean, text[]) IS
345
- $$
346
- Add auditing support to a table.
347
-
348
- Arguments:
349
- target_table: Table name, schema qualified if not on search_path
350
- audit_rows: Record each row change, or only audit at a statement level
351
- audit_query_text: Record the text of the client query that triggered the audit event?
352
- ignored_cols: Columns to exclude from update diffs, ignore updates that change only ignored cols.
353
- $$;
354
-
355
- -- Pg doesn't allow variadic calls with 0 params, so provide a wrapper
356
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean)
357
- RETURNS void AS
358
- $$
359
- SELECT auditing.audit_table($1, $2, $3, ARRAY[]::text[]);
360
- $$
361
- LANGUAGE SQL;
362
-
363
- -- And provide a convenience call wrapper for the simplest case
364
- -- of row-level logging with no excluded cols and query logging enabled.
365
- --
366
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass)
367
- RETURNS void AS
368
- $$
369
- SELECT auditing.audit_table($1, BOOLEAN 't', BOOLEAN 't');
370
- $$
371
- LANGUAGE SQL;
372
-
373
- COMMENT ON FUNCTION auditing.audit_table(regclass) IS
374
- $$
375
- Add auditing support to the given table. Row-level changes will be logged with full client query text. No cols are ignored.
376
- $$;
377
- 
378
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:14
379
-  (0.2ms)  CREATE or REPLACE FUNCTION public.temp_table_exists( varchar)
380
- RETURNS pg_catalog.bool AS
381
- $$
382
- BEGIN
383
- /* check the table exist in database and is visible*/
384
- PERFORM n.nspname, c.relname
385
- FROM pg_catalog.pg_class c
386
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
387
- WHERE n.nspname LIKE 'pg_temp_%' AND pg_catalog.pg_table_is_visible(c.oid)
388
- AND relname = $1;
389
-
390
- IF FOUND THEN
391
- RETURN TRUE;
392
- ELSE
393
- RETURN FALSE;
394
- END IF;
395
-
396
- END;
397
- $$
398
- LANGUAGE 'plpgsql' VOLATILE
399
- 
400
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:16
401
-  (0.2ms)  CREATE OR REPLACE FUNCTION hash_password(password text)
402
- RETURNS text AS
403
- $BODY$
404
- BEGIN
405
- password = crypt(password, gen_salt('bf', 8));
406
-
407
- RETURN password;
408
- END;
409
- $BODY$
410
-
411
- LANGUAGE plpgsql;
412
- 
413
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:39
414
-  (0.2ms)  CREATE OR REPLACE FUNCTION validate_email(email text)
415
- RETURNS text AS
416
- $BODY$
417
- BEGIN
418
- IF email IS NOT NULL THEN
419
- IF email !~* '\A[^@\s\;]+@[^@\s\;]+\.[^@\s\;]+\Z' THEN
420
- RAISE EXCEPTION 'Invalid E-mail format %', email
421
- USING HINT = 'Please check your E-mail format.';
422
- END IF ;
423
- email = lower(email);
424
- END IF ;
425
-
426
- RETURN email;
427
- END;
428
- $BODY$
429
- LANGUAGE plpgsql;
430
- 
431
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:53
432
-  (0.2ms)  CREATE OR REPLACE FUNCTION valid_email_trigger()
433
- RETURNS TRIGGER AS
434
- $BODY$
435
- BEGIN
436
- NEW.email = validate_email(NEW.email);
437
-
438
- RETURN NEW;
439
- END;
440
- $BODY$
441
- LANGUAGE plpgsql;
442
- 
443
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:72
444
- ActiveRecord::SchemaMigration Create (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20180725160802"]]
445
- ↳ bin/rails:14
446
-  (1.6ms) COMMIT
447
- ↳ bin/rails:14
448
- Migrating to CreateBetterRecordTableSizes (20180725201614)
449
-  (0.1ms) BEGIN
450
- ↳ bin/rails:14
451
-  (1.6ms) CREATE TABLE "auditing"."table_sizes" ("oid" bigint, "schema" character varying, "name" character varying, "apx_row_count" float, "total_bytes" bigint, "idx_bytes" bigint, "toast_bytes" bigint, "tbl_bytes" bigint, "total" text, "idx" text, "toast" text, "tbl" text)
452
- ↳ /home/samps/gems/better_record/db/migrate/20180725201614_create_better_record_table_sizes.rb:3
453
-  (1.5ms) ALTER TABLE auditing.table_sizes ADD PRIMARY KEY (oid);
454
- ↳ /home/samps/gems/better_record/db/migrate/20180725201614_create_better_record_table_sizes.rb:20
455
- ActiveRecord::SchemaMigration Create (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20180725201614"]]
456
- ↳ bin/rails:14
457
-  (1.0ms) COMMIT
458
- ↳ bin/rails:14
459
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
460
- ↳ bin/rails:14
461
-  (0.1ms) BEGIN
462
- ↳ bin/rails:14
463
-  (0.1ms) COMMIT
464
- ↳ bin/rails:14
465
-  (0.1ms) SELECT pg_advisory_unlock(3614663923613387715)
466
- ↳ bin/rails:14
467
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
468
- ↳ bin/rails:14
469
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
470
- ↳ bin/rails:14
471
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
472
- ↳ bin/rails:14
473
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
474
- ↳ bin/rails:14
475
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
476
- ↳ bin/rails:14
477
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
478
- ↳ bin/rails:14
479
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
480
- ↳ bin/rails:14
481
-  (112.8ms) DROP DATABASE IF EXISTS "better_record_test"
482
- ↳ bin/rails:14
483
-  (238.7ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
484
- ↳ bin/rails:14
485
- SQL (36.3ms) CREATE EXTENSION IF NOT EXISTS "btree_gin"
486
- ↳ db/schema.rb:16
487
- SQL (10.4ms) CREATE EXTENSION IF NOT EXISTS "hstore"
488
- ↳ db/schema.rb:17
489
- SQL (4.5ms) CREATE EXTENSION IF NOT EXISTS "pg_trgm"
490
- ↳ db/schema.rb:18
491
- SQL (3.6ms) CREATE EXTENSION IF NOT EXISTS "pgcrypto"
492
- ↳ db/schema.rb:19
493
- SQL (0.1ms) CREATE EXTENSION IF NOT EXISTS "plpgsql"
494
- ↳ db/schema.rb:20
495
-  (0.1ms) DROP TABLE IF EXISTS "test_audits" CASCADE
496
- ↳ db/schema.rb:22
497
-  (3.2ms) CREATE TABLE "test_audits" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
498
- ↳ db/schema.rb:22
499
-  (0.1ms) DROP TABLE IF EXISTS "tests" CASCADE
500
- ↳ db/schema.rb:27
501
-  (2.3ms) CREATE TABLE "tests" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
502
- ↳ db/schema.rb:27
503
-  (3.1ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
504
- ↳ db/schema.rb:13
505
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
506
- ↳ db/schema.rb:13
507
-  (1.0ms) INSERT INTO "schema_migrations" (version) VALUES (20180725203710)
508
- ↳ db/schema.rb:13
509
-  (0.8ms) INSERT INTO "schema_migrations" (version) VALUES
510
- (20180725160802),
511
- (20180725201614);
512
-
513
- 
514
- ↳ db/schema.rb:13
515
-  (3.4ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
516
- ↳ db/schema.rb:13
517
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
518
- ↳ db/schema.rb:13
519
-  (0.1ms) BEGIN
520
- ↳ db/schema.rb:13
521
- ActiveRecord::InternalMetadata Create (0.2ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:33:25.764928"], ["updated_at", "2018-07-25 22:33:25.764928"]]
522
- ↳ db/schema.rb:13
523
-  (0.9ms) COMMIT
524
- ↳ db/schema.rb:13
525
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
526
- ↳ bin/rails:14
527
-  (0.1ms) BEGIN
528
- ↳ bin/rails:14
529
- ActiveRecord::InternalMetadata Update (0.2ms) UPDATE "ar_internal_metadata" SET "value" = $1, "updated_at" = $2 WHERE "ar_internal_metadata"."key" = $3 [["value", "test"], ["updated_at", "2018-07-25 22:33:25.768443"], ["key", "environment"]]
530
- ↳ bin/rails:14
531
-  (0.8ms) COMMIT
532
- ↳ bin/rails:14
533
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
534
- ↳ bin/rails:14
535
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
536
- ↳ bin/rails:14
537
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
538
- ↳ bin/rails:14
539
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
540
- ↳ bin/rails:14
541
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
542
- ↳ bin/rails:14
543
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
544
- ↳ bin/rails:14
545
-  (108.3ms) DROP DATABASE IF EXISTS "better_record_development"
546
- ↳ bin/rails:14
547
-  (115.5ms) DROP DATABASE IF EXISTS "better_record_test"
548
- ↳ bin/rails:14
549
-  (258.0ms) CREATE DATABASE "better_record_development" ENCODING = 'utf8'
550
- ↳ bin/rails:14
551
-  (255.3ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
552
- ↳ bin/rails:14
553
- SQL (41.5ms) CREATE EXTENSION IF NOT EXISTS "btree_gin"
554
- ↳ db/schema.rb:16
555
- SQL (9.5ms) CREATE EXTENSION IF NOT EXISTS "hstore"
556
- ↳ db/schema.rb:17
557
- SQL (3.7ms) CREATE EXTENSION IF NOT EXISTS "pg_trgm"
558
- ↳ db/schema.rb:18
559
- SQL (2.6ms) CREATE EXTENSION IF NOT EXISTS "pgcrypto"
560
- ↳ db/schema.rb:19
561
- SQL (0.1ms) CREATE EXTENSION IF NOT EXISTS "plpgsql"
562
- ↳ db/schema.rb:20
563
-  (0.1ms) DROP TABLE IF EXISTS "test_audits" CASCADE
564
- ↳ db/schema.rb:22
565
-  (2.5ms) CREATE TABLE "test_audits" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
566
- ↳ db/schema.rb:22
567
-  (0.1ms) DROP TABLE IF EXISTS "tests" CASCADE
568
- ↳ db/schema.rb:27
569
-  (2.4ms) CREATE TABLE "tests" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
570
- ↳ db/schema.rb:27
571
-  (3.5ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
572
- ↳ db/schema.rb:13
573
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
574
- ↳ db/schema.rb:13
575
-  (0.7ms) INSERT INTO "schema_migrations" (version) VALUES (20180725203710)
576
- ↳ db/schema.rb:13
577
-  (0.8ms) INSERT INTO "schema_migrations" (version) VALUES
578
- (20180725174325),
579
- (20180725174114),
580
- (20180725160802),
581
- (20180725201614);
582
-
583
- 
584
- ↳ db/schema.rb:13
585
-  (2.7ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
586
- ↳ db/schema.rb:13
587
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
588
- ↳ db/schema.rb:13
589
-  (0.1ms) BEGIN
590
- ↳ db/schema.rb:13
591
- ActiveRecord::InternalMetadata Create (0.2ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:34:15.097412"], ["updated_at", "2018-07-25 22:34:15.097412"]]
592
- ↳ db/schema.rb:13
593
-  (0.7ms) COMMIT
594
- ↳ db/schema.rb:13
595
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
596
- ↳ bin/rails:14
597
-  (0.2ms) BEGIN
598
- ↳ bin/rails:14
599
-  (0.2ms) COMMIT
600
- ↳ bin/rails:14
601
- SQL (14.6ms) CREATE EXTENSION IF NOT EXISTS "btree_gin"
602
- ↳ db/schema.rb:16
603
- SQL (7.9ms) CREATE EXTENSION IF NOT EXISTS "hstore"
604
- ↳ db/schema.rb:17
605
- SQL (4.0ms) CREATE EXTENSION IF NOT EXISTS "pg_trgm"
606
- ↳ db/schema.rb:18
607
- SQL (2.7ms) CREATE EXTENSION IF NOT EXISTS "pgcrypto"
608
- ↳ db/schema.rb:19
609
- SQL (0.1ms) CREATE EXTENSION IF NOT EXISTS "plpgsql"
610
- ↳ db/schema.rb:20
611
-  (0.2ms) DROP TABLE IF EXISTS "test_audits" CASCADE
612
- ↳ db/schema.rb:22
613
-  (3.5ms) CREATE TABLE "test_audits" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
614
- ↳ db/schema.rb:22
615
-  (0.2ms) DROP TABLE IF EXISTS "tests" CASCADE
616
- ↳ db/schema.rb:27
617
-  (2.1ms) CREATE TABLE "tests" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
618
- ↳ db/schema.rb:27
619
-  (3.0ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
620
- ↳ db/schema.rb:13
621
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
622
- ↳ db/schema.rb:13
623
-  (0.7ms) INSERT INTO "schema_migrations" (version) VALUES (20180725203710)
624
- ↳ db/schema.rb:13
625
-  (0.8ms) INSERT INTO "schema_migrations" (version) VALUES
626
- (20180725174325),
627
- (20180725174114),
628
- (20180725160802),
629
- (20180725201614);
630
-
631
- 
632
- ↳ db/schema.rb:13
633
-  (3.1ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
634
- ↳ db/schema.rb:13
635
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
636
- ↳ db/schema.rb:13
637
-  (0.1ms) BEGIN
638
- ↳ db/schema.rb:13
639
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:34:15.168863"], ["updated_at", "2018-07-25 22:34:15.168863"]]
640
- ↳ db/schema.rb:13
641
-  (0.6ms) COMMIT
642
- ↳ db/schema.rb:13
643
- ActiveRecord::InternalMetadata Load (0.1ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
644
- ↳ bin/rails:14
645
-  (0.1ms) BEGIN
646
- ↳ bin/rails:14
647
- ActiveRecord::InternalMetadata Update (0.2ms) UPDATE "ar_internal_metadata" SET "value" = $1, "updated_at" = $2 WHERE "ar_internal_metadata"."key" = $3 [["value", "test"], ["updated_at", "2018-07-25 22:34:15.172175"], ["key", "environment"]]
648
- ↳ bin/rails:14
649
-  (0.7ms) COMMIT
650
- ↳ bin/rails:14
651
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
652
- ↳ bin/rails:14
653
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
654
- ↳ bin/rails:14
655
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
656
- ↳ bin/rails:14
657
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
658
- ↳ bin/rails:14
659
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
660
- ↳ bin/rails:14
661
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
662
- ↳ bin/rails:14
663
-  (114.5ms) DROP DATABASE IF EXISTS "better_record_development"
664
- ↳ bin/rails:14
665
-  (113.3ms) DROP DATABASE IF EXISTS "better_record_test"
666
- ↳ bin/rails:14
667
-  (258.2ms) CREATE DATABASE "better_record_development" ENCODING = 'utf8'
668
- ↳ bin/rails:14
669
-  (253.4ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
670
- ↳ bin/rails:14
671
- SQL (36.4ms) CREATE EXTENSION IF NOT EXISTS "btree_gin"
672
- ↳ db/schema.rb:16
673
- SQL (9.6ms) CREATE EXTENSION IF NOT EXISTS "hstore"
674
- ↳ db/schema.rb:17
675
- SQL (4.4ms) CREATE EXTENSION IF NOT EXISTS "pg_trgm"
676
- ↳ db/schema.rb:18
677
- SQL (3.6ms) CREATE EXTENSION IF NOT EXISTS "pgcrypto"
678
- ↳ db/schema.rb:19
679
- SQL (0.2ms) CREATE EXTENSION IF NOT EXISTS "plpgsql"
680
- ↳ db/schema.rb:20
681
-  (0.2ms) DROP TABLE IF EXISTS "test_audits" CASCADE
682
- ↳ db/schema.rb:22
683
-  (3.5ms) CREATE TABLE "test_audits" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
684
- ↳ db/schema.rb:22
685
-  (0.2ms) DROP TABLE IF EXISTS "tests" CASCADE
686
- ↳ db/schema.rb:27
687
-  (2.3ms) CREATE TABLE "tests" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
688
- ↳ db/schema.rb:27
689
-  (3.4ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
690
- ↳ db/schema.rb:13
691
-  (0.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
692
- ↳ db/schema.rb:13
693
-  (0.9ms) INSERT INTO "schema_migrations" (version) VALUES (20180725203710)
694
- ↳ db/schema.rb:13
695
-  (0.8ms) INSERT INTO "schema_migrations" (version) VALUES
696
- (20180725160802),
697
- (20180725201614);
698
-
699
- 
700
- ↳ db/schema.rb:13
701
-  (3.5ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
702
- ↳ db/schema.rb:13
703
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
704
- ↳ db/schema.rb:13
705
-  (0.1ms) BEGIN
706
- ↳ db/schema.rb:13
707
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:34:38.806856"], ["updated_at", "2018-07-25 22:34:38.806856"]]
708
- ↳ db/schema.rb:13
709
-  (0.8ms) COMMIT
710
- ↳ db/schema.rb:13
711
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
712
- ↳ bin/rails:14
713
-  (0.1ms) BEGIN
714
- ↳ bin/rails:14
715
-  (0.1ms) COMMIT
716
- ↳ bin/rails:14
717
- SQL (17.4ms) CREATE EXTENSION IF NOT EXISTS "btree_gin"
718
- ↳ db/schema.rb:16
719
- SQL (8.0ms) CREATE EXTENSION IF NOT EXISTS "hstore"
720
- ↳ db/schema.rb:17
721
- SQL (3.7ms) CREATE EXTENSION IF NOT EXISTS "pg_trgm"
722
- ↳ db/schema.rb:18
723
- SQL (3.0ms) CREATE EXTENSION IF NOT EXISTS "pgcrypto"
724
- ↳ db/schema.rb:19
725
- SQL (0.1ms) CREATE EXTENSION IF NOT EXISTS "plpgsql"
726
- ↳ db/schema.rb:20
727
-  (0.1ms) DROP TABLE IF EXISTS "test_audits" CASCADE
728
- ↳ db/schema.rb:22
729
-  (2.8ms) CREATE TABLE "test_audits" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
730
- ↳ db/schema.rb:22
731
-  (0.1ms) DROP TABLE IF EXISTS "tests" CASCADE
732
- ↳ db/schema.rb:27
733
-  (2.4ms) CREATE TABLE "tests" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
734
- ↳ db/schema.rb:27
735
-  (3.6ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
736
- ↳ db/schema.rb:13
737
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
738
- ↳ db/schema.rb:13
739
-  (1.1ms) INSERT INTO "schema_migrations" (version) VALUES (20180725203710)
740
- ↳ db/schema.rb:13
741
-  (1.0ms) INSERT INTO "schema_migrations" (version) VALUES
742
- (20180725160802),
743
- (20180725201614);
744
-
745
- 
746
- ↳ db/schema.rb:13
747
-  (2.9ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
748
- ↳ db/schema.rb:13
749
- ActiveRecord::InternalMetadata Load (0.1ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
750
- ↳ db/schema.rb:13
751
-  (0.0ms) BEGIN
752
- ↳ db/schema.rb:13
753
- ActiveRecord::InternalMetadata Create (0.2ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:34:38.878614"], ["updated_at", "2018-07-25 22:34:38.878614"]]
754
- ↳ db/schema.rb:13
755
-  (0.6ms) COMMIT
756
- ↳ db/schema.rb:13
757
- ActiveRecord::InternalMetadata Load (0.1ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
758
- ↳ bin/rails:14
759
-  (0.0ms) BEGIN
760
- ↳ bin/rails:14
761
- ActiveRecord::InternalMetadata Update (0.1ms) UPDATE "ar_internal_metadata" SET "value" = $1, "updated_at" = $2 WHERE "ar_internal_metadata"."key" = $3 [["value", "test"], ["updated_at", "2018-07-25 22:34:38.881433"], ["key", "environment"]]
762
- ↳ bin/rails:14
763
-  (0.7ms) COMMIT
764
- ↳ bin/rails:14
765
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
766
- ↳ bin/rails:14
767
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
768
- ↳ bin/rails:14
769
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
770
- ↳ bin/rails:14
771
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
772
- ↳ bin/rails:14
773
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
774
- ↳ bin/rails:14
775
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
776
- ↳ bin/rails:14
777
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
778
- ↳ bin/rails:14
779
-  (108.4ms) DROP DATABASE IF EXISTS "better_record_development"
780
- ↳ bin/rails:14
781
-  (114.2ms) DROP DATABASE IF EXISTS "better_record_test"
782
- ↳ bin/rails:14
783
-  (257.4ms) CREATE DATABASE "better_record_development" ENCODING = 'utf8'
784
- ↳ bin/rails:14
785
-  (257.0ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
786
- ↳ bin/rails:14
787
- SQL (29.6ms) CREATE EXTENSION IF NOT EXISTS "btree_gin"
788
- ↳ db/schema.rb:16
789
- SQL (10.8ms) CREATE EXTENSION IF NOT EXISTS "hstore"
790
- ↳ db/schema.rb:17
791
- SQL (4.0ms) CREATE EXTENSION IF NOT EXISTS "pg_trgm"
792
- ↳ db/schema.rb:18
793
- SQL (2.9ms) CREATE EXTENSION IF NOT EXISTS "pgcrypto"
794
- ↳ db/schema.rb:19
795
- SQL (0.1ms) CREATE EXTENSION IF NOT EXISTS "plpgsql"
796
- ↳ db/schema.rb:20
797
-  (0.1ms) DROP TABLE IF EXISTS "test_audits" CASCADE
798
- ↳ db/schema.rb:22
799
-  (3.1ms) CREATE TABLE "test_audits" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
800
- ↳ db/schema.rb:22
801
-  (0.1ms) DROP TABLE IF EXISTS "tests" CASCADE
802
- ↳ db/schema.rb:27
803
-  (2.8ms) CREATE TABLE "tests" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
804
- ↳ db/schema.rb:27
805
-  (3.4ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
806
- ↳ db/schema.rb:13
807
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
808
- ↳ db/schema.rb:13
809
-  (0.9ms) INSERT INTO "schema_migrations" (version) VALUES (20180725203710)
810
- ↳ db/schema.rb:13
811
-  (0.9ms) INSERT INTO "schema_migrations" (version) VALUES
812
- (20180725160802),
813
- (20180725201614);
814
-
815
- 
816
- ↳ db/schema.rb:13
817
-  (3.0ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
818
- ↳ db/schema.rb:13
819
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
820
- ↳ db/schema.rb:13
821
-  (0.1ms) BEGIN
822
- ↳ db/schema.rb:13
823
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:39:52.579433"], ["updated_at", "2018-07-25 22:39:52.579433"]]
824
- ↳ db/schema.rb:13
825
-  (0.9ms) COMMIT
826
- ↳ db/schema.rb:13
827
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
828
- ↳ bin/rails:14
829
-  (0.1ms) BEGIN
830
- ↳ bin/rails:14
831
-  (0.1ms) COMMIT
832
- ↳ bin/rails:14
833
- SQL (14.6ms) CREATE EXTENSION IF NOT EXISTS "btree_gin"
834
- ↳ db/schema.rb:16
835
- SQL (7.7ms) CREATE EXTENSION IF NOT EXISTS "hstore"
836
- ↳ db/schema.rb:17
837
- SQL (3.7ms) CREATE EXTENSION IF NOT EXISTS "pg_trgm"
838
- ↳ db/schema.rb:18
839
- SQL (3.4ms) CREATE EXTENSION IF NOT EXISTS "pgcrypto"
840
- ↳ db/schema.rb:19
841
- SQL (0.1ms) CREATE EXTENSION IF NOT EXISTS "plpgsql"
842
- ↳ db/schema.rb:20
843
-  (0.2ms) DROP TABLE IF EXISTS "test_audits" CASCADE
844
- ↳ db/schema.rb:22
845
-  (3.0ms) CREATE TABLE "test_audits" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
846
- ↳ db/schema.rb:22
847
-  (0.2ms) DROP TABLE IF EXISTS "tests" CASCADE
848
- ↳ db/schema.rb:27
849
-  (2.2ms) CREATE TABLE "tests" ("id" bigserial primary key, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
850
- ↳ db/schema.rb:27
851
-  (3.0ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
852
- ↳ db/schema.rb:13
853
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
854
- ↳ db/schema.rb:13
855
-  (0.8ms) INSERT INTO "schema_migrations" (version) VALUES (20180725203710)
856
- ↳ db/schema.rb:13
857
-  (0.7ms) INSERT INTO "schema_migrations" (version) VALUES
858
- (20180725160802),
859
- (20180725201614);
860
-
861
- 
862
- ↳ db/schema.rb:13
863
-  (3.7ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
864
- ↳ db/schema.rb:13
865
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
866
- ↳ db/schema.rb:13
867
-  (0.1ms) BEGIN
868
- ↳ db/schema.rb:13
869
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:39:52.646441"], ["updated_at", "2018-07-25 22:39:52.646441"]]
870
- ↳ db/schema.rb:13
871
-  (0.8ms) COMMIT
872
- ↳ db/schema.rb:13
873
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
874
- ↳ bin/rails:14
875
-  (0.1ms) BEGIN
876
- ↳ bin/rails:14
877
- ActiveRecord::InternalMetadata Update (0.2ms) UPDATE "ar_internal_metadata" SET "value" = $1, "updated_at" = $2 WHERE "ar_internal_metadata"."key" = $3 [["value", "test"], ["updated_at", "2018-07-25 22:39:52.649708"], ["key", "environment"]]
878
- ↳ bin/rails:14
879
-  (0.7ms) COMMIT
880
- ↳ bin/rails:14
881
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
882
- ↳ bin/rails:14
883
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
884
- ↳ bin/rails:14
885
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
886
- ↳ bin/rails:14
887
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
888
- ↳ bin/rails:14
889
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
890
- ↳ bin/rails:14
891
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
892
- ↳ bin/rails:14
893
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
894
- ↳ bin/rails:14
895
-  (108.5ms) DROP DATABASE IF EXISTS "better_record_development"
896
- ↳ bin/rails:14
897
-  (114.2ms) DROP DATABASE IF EXISTS "better_record_test"
898
- ↳ bin/rails:14
899
-  (256.0ms) CREATE DATABASE "better_record_development" ENCODING = 'utf8'
900
- ↳ bin/rails:14
901
-  (259.4ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
902
- ↳ bin/rails:14
903
-  (5.2ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
904
- ↳ bin/rails:14
905
-  (3.5ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
906
- ↳ bin/rails:14
907
-  (0.4ms) SELECT pg_try_advisory_lock(3614663923613387715)
908
- ↳ bin/rails:14
909
-  (0.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
910
- ↳ bin/rails:14
911
- Migrating to CreateBetterRecordDBFunctions (20180725160802)
912
-  (0.1ms) BEGIN
913
- ↳ bin/rails:14
914
-  (5.4ms) CREATE EXTENSION IF NOT EXISTS pg_trgm;
915
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:3
916
-  (12.0ms) CREATE EXTENSION IF NOT EXISTS btree_gin;
917
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:4
918
-  (1.9ms) CREATE EXTENSION IF NOT EXISTS pgcrypto;
919
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:5
920
-  (15.9ms) -- An audit history is important on most tables. Provide an audit trigger that logs to
921
- -- a dedicated audit table for the major relations.
922
- --
923
- -- This file should be generic and not depend on application roles or structures,
924
- -- as it's being listed here:
925
- --
926
- -- https://wiki.postgresql.org/wiki/Audit_trigger_91plus
927
- --
928
- -- This trigger was originally based on
929
- -- http://wiki.postgresql.org/wiki/Audit_trigger
930
- -- but has been completely rewritten.
931
- --
932
- -- Should really be converted into a relocatable EXTENSION, with control and upgrade files.
933
-
934
- CREATE EXTENSION IF NOT EXISTS hstore;
935
-
936
- CREATE SCHEMA auditing;
937
- REVOKE ALL ON SCHEMA auditing FROM public;
938
-
939
- COMMENT ON SCHEMA auditing IS 'Out-of-table audit/history logging tables and trigger functions';
940
-
941
- --
942
- -- Audited data. Lots of information is available, it's just a matter of how much
943
- -- you really want to record. See:
944
- --
945
- -- http://www.postgresql.org/docs/9.1/static/functions-info.html
946
- --
947
- -- Remember, every column you add takes up more audit table space and slows audit
948
- -- inserts.
949
- --
950
- -- Every index you add has a big impact too, so avoid adding indexes to the
951
- -- audit table unless you REALLY need them. The hstore GIST indexes are
952
- -- particularly expensive.
953
- --
954
- -- It is sometimes worth copying the audit table, or a coarse subset of it that
955
- -- you're interested in, into a temporary table where you CREATE any useful
956
- -- indexes and do your analysis.
957
- --
958
- CREATE TABLE auditing.logged_actions (
959
- event_id bigserial primary key,
960
- schema_name text not null,
961
- table_name text not null,
962
- relid oid not null,
963
- session_user_name text,
964
- app_user_id integer,
965
- app_user_type text,
966
- app_ip_address inet,
967
- action_tstamp_tx TIMESTAMP WITH TIME ZONE NOT NULL,
968
- action_tstamp_stm TIMESTAMP WITH TIME ZONE NOT NULL,
969
- action_tstamp_clk TIMESTAMP WITH TIME ZONE NOT NULL,
970
- transaction_id bigint,
971
- application_name text,
972
- client_addr inet,
973
- client_port integer,
974
- client_query text,
975
- action TEXT NOT NULL CHECK (action IN ('I','D','U', 'T')),
976
- row_id bigint,
977
- row_data hstore,
978
- changed_fields hstore,
979
- statement_only boolean not null
980
- );
981
-
982
- REVOKE ALL ON auditing.logged_actions FROM public;
983
-
984
- COMMENT ON TABLE auditing.logged_actions IS 'History of auditable actions on audited tables, from auditing.if_modified_func()';
985
- COMMENT ON COLUMN auditing.logged_actions.event_id IS 'Unique identifier for each auditable event';
986
- COMMENT ON COLUMN auditing.logged_actions.schema_name IS 'Database schema audited table for this event is in';
987
- COMMENT ON COLUMN auditing.logged_actions.table_name IS 'Non-schema-qualified table name of table event occured in';
988
- COMMENT ON COLUMN auditing.logged_actions.relid IS 'Table OID. Changes with drop/create. Get with ''tablename''::regclass';
989
- COMMENT ON COLUMN auditing.logged_actions.session_user_name IS 'Login / session user whose statement caused the audited event';
990
- COMMENT ON COLUMN auditing.logged_actions.app_user_id IS 'Application-provided polymorphic user id';
991
- COMMENT ON COLUMN auditing.logged_actions.app_user_type IS 'Application-provided polymorphic user type';
992
- COMMENT ON COLUMN auditing.logged_actions.app_ip_address IS 'Application-provided ip address of user whose statement caused the audited event';
993
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_tx IS 'Transaction start timestamp for tx in which audited event occurred';
994
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_stm IS 'Statement start timestamp for tx in which audited event occurred';
995
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_clk IS 'Wall clock time at which audited event''s trigger call occurred';
996
- 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.';
997
- COMMENT ON COLUMN auditing.logged_actions.client_addr IS 'IP address of client that issued query. Null for unix domain socket.';
998
- COMMENT ON COLUMN auditing.logged_actions.client_port IS 'Remote peer IP port address of client that issued query. Undefined for unix socket.';
999
- COMMENT ON COLUMN auditing.logged_actions.client_query IS 'Top-level query that caused this auditable event. May be more than one statement.';
1000
- COMMENT ON COLUMN auditing.logged_actions.application_name IS 'Application name set when this audit event occurred. Can be changed in-session by client.';
1001
- COMMENT ON COLUMN auditing.logged_actions.action IS 'Action type; I = insert, D = delete, U = update, T = truncate';
1002
- COMMENT ON COLUMN auditing.logged_actions.row_id IS 'Record primary_key. Null for statement-level trigger. Prefers NEW.id if exists';
1003
- 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.';
1004
- COMMENT ON COLUMN auditing.logged_actions.changed_fields IS 'New values of fields changed by UPDATE. Null except for row-level UPDATE events.';
1005
- 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';
1006
-
1007
- CREATE INDEX logged_actions_relid_idx ON auditing.logged_actions(relid);
1008
- CREATE INDEX logged_actions_action_tstamp_tx_stm_idx ON auditing.logged_actions(action_tstamp_stm);
1009
- CREATE INDEX logged_actions_action_idx ON auditing.logged_actions(action);
1010
- CREATE INDEX logged_actions_row_id_idx ON auditing.logged_actions(row_id);
1011
-
1012
- CREATE OR REPLACE FUNCTION auditing.if_modified_func()
1013
- RETURNS TRIGGER AS
1014
- $$
1015
- DECLARE
1016
- audit_row auditing.logged_actions;
1017
- include_values boolean;
1018
- log_diffs boolean;
1019
- h_old hstore;
1020
- h_new hstore;
1021
- user_row record;
1022
- excluded_cols text[] = ARRAY[]::text[];
1023
- pk_val_query text;
1024
- BEGIN
1025
- IF TG_WHEN <> 'AFTER' THEN
1026
- RAISE EXCEPTION 'auditing.if_modified_func() may only run as an AFTER trigger';
1027
- END IF;
1028
-
1029
- audit_row = ROW(
1030
- nextval('auditing.logged_actions_event_id_seq'), -- event_id
1031
- TG_TABLE_SCHEMA::text, -- schema_name
1032
- TG_TABLE_NAME::text, -- table_name
1033
- TG_RELID, -- relation OID for much quicker searches
1034
- session_user::text, -- session_user_name
1035
- NULL, NULL, NULL, -- app_user_id, app_user_type, app_ip_address
1036
- current_timestamp, -- action_tstamp_tx
1037
- statement_timestamp(), -- action_tstamp_stm
1038
- clock_timestamp(), -- action_tstamp_clk
1039
- txid_current(), -- transaction ID
1040
- current_setting('application_name'), -- client application
1041
- inet_client_addr(), -- client_addr
1042
- inet_client_port(), -- client_port
1043
- current_query(), -- top-level query or queries (if multistatement) from client
1044
- substring(TG_OP,1,1), -- action
1045
- NULL, NULL, NULL, -- row_id, row_data, changed_fields
1046
- 'f' -- statement_only
1047
- );
1048
-
1049
- IF NOT TG_ARGV[0]::boolean IS DISTINCT FROM 'f'::boolean THEN
1050
- audit_row.client_query = NULL;
1051
- END IF;
1052
-
1053
- IF ((TG_ARGV[1] IS NOT NULL) AND (TG_LEVEL = 'ROW')) THEN
1054
- pk_val_query = 'SELECT $1.' || quote_ident(TG_ARGV[1]::text);
1055
-
1056
- IF (TG_OP IS DISTINCT FROM 'DELETE') THEN
1057
- EXECUTE pk_val_query INTO audit_row.row_id USING NEW;
1058
- END IF;
1059
-
1060
- IF audit_row.row_id IS NULL THEN
1061
- EXECUTE pk_val_query INTO audit_row.row_id USING OLD;
1062
- END IF;
1063
- END IF;
1064
-
1065
- IF TG_ARGV[2] IS NOT NULL THEN
1066
- excluded_cols = TG_ARGV[2]::text[];
1067
- END IF;
1068
-
1069
-
1070
-
1071
- IF (TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW') THEN
1072
- audit_row.row_data = hstore(OLD.*) - excluded_cols;
1073
- audit_row.changed_fields = (hstore(NEW.*) - audit_row.row_data) - excluded_cols;
1074
- IF audit_row.changed_fields = hstore('') THEN
1075
- -- All changed fields are ignored. Skip this update.
1076
- RETURN NULL;
1077
- END IF;
1078
- ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
1079
- audit_row.row_data = hstore(OLD.*) - excluded_cols;
1080
- ELSIF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
1081
- audit_row.row_data = hstore(NEW.*) - excluded_cols;
1082
- ELSIF (TG_LEVEL = 'STATEMENT' AND TG_OP IN ('INSERT','UPDATE','DELETE','TRUNCATE')) THEN
1083
- audit_row.statement_only = 't';
1084
- ELSE
1085
- RAISE EXCEPTION '[auditing.if_modified_func] - Trigger func added as trigger for unhandled case: %, %',TG_OP, TG_LEVEL;
1086
- RETURN NULL;
1087
- END IF;
1088
-
1089
- -- inject app_user data into audit
1090
- BEGIN
1091
- PERFORM
1092
- n.nspname, c.relname
1093
- FROM
1094
- pg_catalog.pg_class c
1095
- LEFT JOIN
1096
- pg_catalog.pg_namespace n
1097
- ON n.oid = c.relnamespace
1098
- WHERE
1099
- n.nspname like 'pg_temp_%'
1100
- AND
1101
- c.relname = '_app_user';
1102
-
1103
- IF FOUND THEN
1104
- FOR user_row IN SELECT * FROM _app_user LIMIT 1 LOOP
1105
- audit_row.app_user_id = user_row.user_id;
1106
- audit_row.app_user_type = user_row.user_type;
1107
- audit_row.app_ip_address = user_row.ip_address;
1108
- END LOOP;
1109
- END IF;
1110
- END;
1111
- -- end app_user data
1112
-
1113
- INSERT INTO auditing.logged_actions VALUES (audit_row.*);
1114
- RETURN NULL;
1115
- END;
1116
- $$
1117
- LANGUAGE plpgsql
1118
- SECURITY DEFINER
1119
- SET search_path = pg_catalog, public;
1120
-
1121
-
1122
- COMMENT ON FUNCTION auditing.if_modified_func() IS
1123
- $$
1124
- Track changes to a table at the statement and/or row level.
1125
-
1126
- Optional parameters to trigger in CREATE TRIGGER call:
1127
-
1128
- param 0: boolean, whether to log the query text. Default 't'.
1129
-
1130
- param 1: text, primary_key_column of audited table if bigint.
1131
-
1132
- param 2: text[], columns to ignore in updates. Default [].
1133
-
1134
- Updates to ignored cols are omitted from changed_fields.
1135
-
1136
- Updates with only ignored cols changed are not inserted
1137
- into the audit log.
1138
-
1139
- Almost all the processing work is still done for updates
1140
- that ignored. If you need to save the load, you need to use
1141
- WHEN clause on the trigger instead.
1142
-
1143
- No warning or error is issued if ignored_cols contains columns
1144
- that do not exist in the target table. This lets you specify
1145
- a standard set of ignored columns.
1146
-
1147
- There is no parameter to disable logging of values. Add this trigger as
1148
- a 'FOR EACH STATEMENT' rather than 'FOR EACH ROW' trigger if you do not
1149
- want to log row values.
1150
-
1151
- Note that the user name logged is the login role for the session. The audit trigger
1152
- cannot obtain the active role because it is reset by the SECURITY DEFINER invocation
1153
- of the audit trigger its self.
1154
- $$;
1155
-
1156
-
1157
- CREATE OR REPLACE FUNCTION auditing.get_primary_key_column(target_table text)
1158
- RETURNS text AS
1159
- $$
1160
- DECLARE
1161
- _pk_query_text text;
1162
- _pk_column_name text;
1163
- BEGIN
1164
- _pk_query_text = 'SELECT a.attname ' ||
1165
- 'FROM pg_index i ' ||
1166
- 'JOIN pg_attribute a ON a.attrelid = i.indrelid ' ||
1167
- ' AND a.attnum = ANY(i.indkey) ' ||
1168
- 'WHERE i.indrelid = ' || quote_literal(target_table::TEXT) || '::regclass ' ||
1169
- 'AND i.indisprimary ' ||
1170
- 'AND format_type(a.atttypid, a.atttypmod) = ' || quote_literal('bigint'::TEXT) ||
1171
- 'LIMIT 1';
1172
-
1173
- EXECUTE _pk_query_text INTO _pk_column_name;
1174
- raise notice 'Value %', _pk_column_name;
1175
- return _pk_column_name;
1176
- END;
1177
- $$
1178
- LANGUAGE plpgsql;
1179
-
1180
- COMMENT ON FUNCTION auditing.get_primary_key_column(text) IS
1181
- $$
1182
- Get primary key column name if single PK and type bigint.
1183
-
1184
- Arguments:
1185
- target_table: Table name, schema qualified if not on search_path
1186
- $$;
1187
-
1188
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean, ignored_cols text[])
1189
- RETURNS void AS
1190
- $$
1191
- DECLARE
1192
- stm_targets text = 'INSERT OR UPDATE OR DELETE OR TRUNCATE';
1193
- _q_txt text;
1194
- _pk_column_name text;
1195
- _pk_column_snip text;
1196
- _ignored_cols_snip text = '';
1197
- BEGIN
1198
- EXECUTE 'DROP TRIGGER IF EXISTS audit_trigger_row ON ' || quote_ident(target_table::TEXT);
1199
- EXECUTE 'DROP TRIGGER IF EXISTS audit_trigger_stm ON ' || quote_ident(target_table::TEXT);
1200
-
1201
- IF audit_rows THEN
1202
- _pk_column_name = auditing.get_primary_key_column(target_table::TEXT);
1203
-
1204
- IF _pk_column_name IS NOT NULL THEN
1205
- _pk_column_snip = ', ' || quote_literal(_pk_column_name);
1206
- ELSE
1207
- _pk_column_snip = ', NULL';
1208
- END IF;
1209
-
1210
- IF array_length(ignored_cols,1) > 0 THEN
1211
- _ignored_cols_snip = ', ' || quote_literal(ignored_cols);
1212
- END IF;
1213
- _q_txt = 'CREATE TRIGGER audit_trigger_row AFTER INSERT OR UPDATE OR DELETE ON ' ||
1214
- quote_ident(target_table::TEXT) ||
1215
- ' FOR EACH ROW EXECUTE PROCEDURE auditing.if_modified_func(' ||
1216
- quote_literal(audit_query_text) || _pk_column_snip || _ignored_cols_snip || ');';
1217
- RAISE NOTICE '%',_q_txt;
1218
- EXECUTE _q_txt;
1219
- stm_targets = 'TRUNCATE';
1220
- ELSE
1221
- END IF;
1222
-
1223
- _q_txt = 'CREATE TRIGGER audit_trigger_stm AFTER ' || stm_targets || ' ON ' ||
1224
- target_table ||
1225
- ' FOR EACH STATEMENT EXECUTE PROCEDURE auditing.if_modified_func('||
1226
- quote_literal(audit_query_text) || ');';
1227
- RAISE NOTICE '%',_q_txt;
1228
- EXECUTE _q_txt;
1229
-
1230
- END;
1231
- $$
1232
- LANGUAGE plpgsql;
1233
-
1234
- COMMENT ON FUNCTION auditing.audit_table(regclass, boolean, boolean, text[]) IS
1235
- $$
1236
- Add auditing support to a table.
1237
-
1238
- Arguments:
1239
- target_table: Table name, schema qualified if not on search_path
1240
- audit_rows: Record each row change, or only audit at a statement level
1241
- audit_query_text: Record the text of the client query that triggered the audit event?
1242
- ignored_cols: Columns to exclude from update diffs, ignore updates that change only ignored cols.
1243
- $$;
1244
-
1245
- -- Pg doesn't allow variadic calls with 0 params, so provide a wrapper
1246
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean)
1247
- RETURNS void AS
1248
- $$
1249
- SELECT auditing.audit_table($1, $2, $3, ARRAY[]::text[]);
1250
- $$
1251
- LANGUAGE SQL;
1252
-
1253
- -- And provide a convenience call wrapper for the simplest case
1254
- -- of row-level logging with no excluded cols and query logging enabled.
1255
- --
1256
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass)
1257
- RETURNS void AS
1258
- $$
1259
- SELECT auditing.audit_table($1, BOOLEAN 't', BOOLEAN 't');
1260
- $$
1261
- LANGUAGE SQL;
1262
-
1263
- COMMENT ON FUNCTION auditing.audit_table(regclass) IS
1264
- $$
1265
- Add auditing support to the given table. Row-level changes will be logged with full client query text. No cols are ignored.
1266
- $$;
1267
- 
1268
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:14
1269
-  (0.2ms)  CREATE or REPLACE FUNCTION public.temp_table_exists( varchar)
1270
- RETURNS pg_catalog.bool AS
1271
- $$
1272
- BEGIN
1273
- /* check the table exist in database and is visible*/
1274
- PERFORM n.nspname, c.relname
1275
- FROM pg_catalog.pg_class c
1276
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
1277
- WHERE n.nspname LIKE 'pg_temp_%' AND pg_catalog.pg_table_is_visible(c.oid)
1278
- AND relname = $1;
1279
-
1280
- IF FOUND THEN
1281
- RETURN TRUE;
1282
- ELSE
1283
- RETURN FALSE;
1284
- END IF;
1285
-
1286
- END;
1287
- $$
1288
- LANGUAGE 'plpgsql' VOLATILE
1289
- 
1290
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:16
1291
-  (0.2ms)  CREATE OR REPLACE FUNCTION hash_password(password text)
1292
- RETURNS text AS
1293
- $BODY$
1294
- BEGIN
1295
- password = crypt(password, gen_salt('bf', 8));
1296
-
1297
- RETURN password;
1298
- END;
1299
- $BODY$
1300
-
1301
- LANGUAGE plpgsql;
1302
- 
1303
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:39
1304
-  (0.2ms)  CREATE OR REPLACE FUNCTION validate_email(email text)
1305
- RETURNS text AS
1306
- $BODY$
1307
- BEGIN
1308
- IF email IS NOT NULL THEN
1309
- IF email !~* '\A[^@\s\;]+@[^@\s\;]+\.[^@\s\;]+\Z' THEN
1310
- RAISE EXCEPTION 'Invalid E-mail format %', email
1311
- USING HINT = 'Please check your E-mail format.';
1312
- END IF ;
1313
- email = lower(email);
1314
- END IF ;
1315
-
1316
- RETURN email;
1317
- END;
1318
- $BODY$
1319
- LANGUAGE plpgsql;
1320
- 
1321
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:53
1322
-  (0.2ms)  CREATE OR REPLACE FUNCTION valid_email_trigger()
1323
- RETURNS TRIGGER AS
1324
- $BODY$
1325
- BEGIN
1326
- NEW.email = validate_email(NEW.email);
1327
-
1328
- RETURN NEW;
1329
- END;
1330
- $BODY$
1331
- LANGUAGE plpgsql;
1332
- 
1333
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:72
1334
- ActiveRecord::SchemaMigration Create (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20180725160802"]]
1335
- ↳ bin/rails:14
1336
-  (5.4ms) COMMIT
1337
- ↳ bin/rails:14
1338
- Migrating to CreateBetterRecordTableSizes (20180725201614)
1339
-  (0.2ms) BEGIN
1340
- ↳ bin/rails:14
1341
-  (1.7ms) CREATE TABLE "auditing"."table_sizes" ("oid" bigint, "schema" character varying, "name" character varying, "apx_row_count" float, "total_bytes" bigint, "idx_bytes" bigint, "toast_bytes" bigint, "tbl_bytes" bigint, "total" text, "idx" text, "toast" text, "tbl" text)
1342
- ↳ /home/samps/gems/better_record/db/migrate/20180725201614_create_better_record_table_sizes.rb:3
1343
-  (1.3ms) ALTER TABLE auditing.table_sizes ADD PRIMARY KEY (oid);
1344
- ↳ /home/samps/gems/better_record/db/migrate/20180725201614_create_better_record_table_sizes.rb:20
1345
- ActiveRecord::SchemaMigration Create (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20180725201614"]]
1346
- ↳ bin/rails:14
1347
-  (0.6ms) COMMIT
1348
- ↳ bin/rails:14
1349
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
1350
- ↳ bin/rails:14
1351
-  (0.1ms) BEGIN
1352
- ↳ bin/rails:14
1353
- ActiveRecord::InternalMetadata Create (0.2ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:41:08.739911"], ["updated_at", "2018-07-25 22:41:08.739911"]]
1354
- ↳ bin/rails:14
1355
-  (0.7ms) COMMIT
1356
- ↳ bin/rails:14
1357
-  (0.1ms) SELECT pg_advisory_unlock(3614663923613387715)
1358
- ↳ bin/rails:14
1359
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1360
- ↳ bin/rails:14
1361
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1362
- ↳ bin/rails:14
1363
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
1364
- ↳ bin/rails:14
1365
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1366
- ↳ bin/rails:14
1367
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
1368
- ↳ bin/rails:14
1369
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1370
- ↳ bin/rails:14
1371
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
1372
- ↳ bin/rails:14
1373
-  (108.6ms) DROP DATABASE IF EXISTS "better_record_development"
1374
- ↳ bin/rails:14
1375
-  (112.8ms) DROP DATABASE IF EXISTS "better_record_test"
1376
- ↳ bin/rails:14
1377
-  (242.4ms) CREATE DATABASE "better_record_development" ENCODING = 'utf8'
1378
- ↳ bin/rails:14
1379
-  (255.9ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
1380
- ↳ bin/rails:14
1381
-  (5.4ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
1382
- ↳ bin/rails:14
1383
-  (3.3ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
1384
- ↳ bin/rails:14
1385
-  (0.1ms) SELECT pg_try_advisory_lock(3614663923613387715)
1386
- ↳ bin/rails:14
1387
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1388
- ↳ bin/rails:14
1389
- Migrating to CreateBetterRecordDBFunctions (20180725160802)
1390
-  (0.1ms) BEGIN
1391
- ↳ bin/rails:14
1392
-  (3.2ms) CREATE EXTENSION IF NOT EXISTS pg_trgm;
1393
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:3
1394
-  (10.2ms) CREATE EXTENSION IF NOT EXISTS btree_gin;
1395
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:4
1396
-  (2.0ms) CREATE EXTENSION IF NOT EXISTS pgcrypto;
1397
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:5
1398
-  (13.6ms) -- An audit history is important on most tables. Provide an audit trigger that logs to
1399
- -- a dedicated audit table for the major relations.
1400
- --
1401
- -- This file should be generic and not depend on application roles or structures,
1402
- -- as it's being listed here:
1403
- --
1404
- -- https://wiki.postgresql.org/wiki/Audit_trigger_91plus
1405
- --
1406
- -- This trigger was originally based on
1407
- -- http://wiki.postgresql.org/wiki/Audit_trigger
1408
- -- but has been completely rewritten.
1409
- --
1410
- -- Should really be converted into a relocatable EXTENSION, with control and upgrade files.
1411
-
1412
- CREATE EXTENSION IF NOT EXISTS hstore;
1413
-
1414
- CREATE SCHEMA auditing;
1415
- REVOKE ALL ON SCHEMA auditing FROM public;
1416
-
1417
- COMMENT ON SCHEMA auditing IS 'Out-of-table audit/history logging tables and trigger functions';
1418
-
1419
- --
1420
- -- Audited data. Lots of information is available, it's just a matter of how much
1421
- -- you really want to record. See:
1422
- --
1423
- -- http://www.postgresql.org/docs/9.1/static/functions-info.html
1424
- --
1425
- -- Remember, every column you add takes up more audit table space and slows audit
1426
- -- inserts.
1427
- --
1428
- -- Every index you add has a big impact too, so avoid adding indexes to the
1429
- -- audit table unless you REALLY need them. The hstore GIST indexes are
1430
- -- particularly expensive.
1431
- --
1432
- -- It is sometimes worth copying the audit table, or a coarse subset of it that
1433
- -- you're interested in, into a temporary table where you CREATE any useful
1434
- -- indexes and do your analysis.
1435
- --
1436
- CREATE TABLE auditing.logged_actions (
1437
- event_id bigserial primary key,
1438
- schema_name text not null,
1439
- table_name text not null,
1440
- relid oid not null,
1441
- session_user_name text,
1442
- app_user_id integer,
1443
- app_user_type text,
1444
- app_ip_address inet,
1445
- action_tstamp_tx TIMESTAMP WITH TIME ZONE NOT NULL,
1446
- action_tstamp_stm TIMESTAMP WITH TIME ZONE NOT NULL,
1447
- action_tstamp_clk TIMESTAMP WITH TIME ZONE NOT NULL,
1448
- transaction_id bigint,
1449
- application_name text,
1450
- client_addr inet,
1451
- client_port integer,
1452
- client_query text,
1453
- action TEXT NOT NULL CHECK (action IN ('I','D','U', 'T')),
1454
- row_id bigint,
1455
- row_data hstore,
1456
- changed_fields hstore,
1457
- statement_only boolean not null
1458
- );
1459
-
1460
- REVOKE ALL ON auditing.logged_actions FROM public;
1461
-
1462
- COMMENT ON TABLE auditing.logged_actions IS 'History of auditable actions on audited tables, from auditing.if_modified_func()';
1463
- COMMENT ON COLUMN auditing.logged_actions.event_id IS 'Unique identifier for each auditable event';
1464
- COMMENT ON COLUMN auditing.logged_actions.schema_name IS 'Database schema audited table for this event is in';
1465
- COMMENT ON COLUMN auditing.logged_actions.table_name IS 'Non-schema-qualified table name of table event occured in';
1466
- COMMENT ON COLUMN auditing.logged_actions.relid IS 'Table OID. Changes with drop/create. Get with ''tablename''::regclass';
1467
- COMMENT ON COLUMN auditing.logged_actions.session_user_name IS 'Login / session user whose statement caused the audited event';
1468
- COMMENT ON COLUMN auditing.logged_actions.app_user_id IS 'Application-provided polymorphic user id';
1469
- COMMENT ON COLUMN auditing.logged_actions.app_user_type IS 'Application-provided polymorphic user type';
1470
- COMMENT ON COLUMN auditing.logged_actions.app_ip_address IS 'Application-provided ip address of user whose statement caused the audited event';
1471
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_tx IS 'Transaction start timestamp for tx in which audited event occurred';
1472
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_stm IS 'Statement start timestamp for tx in which audited event occurred';
1473
- COMMENT ON COLUMN auditing.logged_actions.action_tstamp_clk IS 'Wall clock time at which audited event''s trigger call occurred';
1474
- 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.';
1475
- COMMENT ON COLUMN auditing.logged_actions.client_addr IS 'IP address of client that issued query. Null for unix domain socket.';
1476
- COMMENT ON COLUMN auditing.logged_actions.client_port IS 'Remote peer IP port address of client that issued query. Undefined for unix socket.';
1477
- COMMENT ON COLUMN auditing.logged_actions.client_query IS 'Top-level query that caused this auditable event. May be more than one statement.';
1478
- COMMENT ON COLUMN auditing.logged_actions.application_name IS 'Application name set when this audit event occurred. Can be changed in-session by client.';
1479
- COMMENT ON COLUMN auditing.logged_actions.action IS 'Action type; I = insert, D = delete, U = update, T = truncate';
1480
- COMMENT ON COLUMN auditing.logged_actions.row_id IS 'Record primary_key. Null for statement-level trigger. Prefers NEW.id if exists';
1481
- 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.';
1482
- COMMENT ON COLUMN auditing.logged_actions.changed_fields IS 'New values of fields changed by UPDATE. Null except for row-level UPDATE events.';
1483
- 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';
1484
-
1485
- CREATE INDEX logged_actions_relid_idx ON auditing.logged_actions(relid);
1486
- CREATE INDEX logged_actions_action_tstamp_tx_stm_idx ON auditing.logged_actions(action_tstamp_stm);
1487
- CREATE INDEX logged_actions_action_idx ON auditing.logged_actions(action);
1488
- CREATE INDEX logged_actions_row_id_idx ON auditing.logged_actions(row_id);
1489
-
1490
- CREATE OR REPLACE FUNCTION auditing.if_modified_func()
1491
- RETURNS TRIGGER AS
1492
- $$
1493
- DECLARE
1494
- audit_row auditing.logged_actions;
1495
- include_values boolean;
1496
- log_diffs boolean;
1497
- h_old hstore;
1498
- h_new hstore;
1499
- user_row record;
1500
- excluded_cols text[] = ARRAY[]::text[];
1501
- pk_val_query text;
1502
- BEGIN
1503
- IF TG_WHEN <> 'AFTER' THEN
1504
- RAISE EXCEPTION 'auditing.if_modified_func() may only run as an AFTER trigger';
1505
- END IF;
1506
-
1507
- audit_row = ROW(
1508
- nextval('auditing.logged_actions_event_id_seq'), -- event_id
1509
- TG_TABLE_SCHEMA::text, -- schema_name
1510
- TG_TABLE_NAME::text, -- table_name
1511
- TG_RELID, -- relation OID for much quicker searches
1512
- session_user::text, -- session_user_name
1513
- NULL, NULL, NULL, -- app_user_id, app_user_type, app_ip_address
1514
- current_timestamp, -- action_tstamp_tx
1515
- statement_timestamp(), -- action_tstamp_stm
1516
- clock_timestamp(), -- action_tstamp_clk
1517
- txid_current(), -- transaction ID
1518
- current_setting('application_name'), -- client application
1519
- inet_client_addr(), -- client_addr
1520
- inet_client_port(), -- client_port
1521
- current_query(), -- top-level query or queries (if multistatement) from client
1522
- substring(TG_OP,1,1), -- action
1523
- NULL, NULL, NULL, -- row_id, row_data, changed_fields
1524
- 'f' -- statement_only
1525
- );
1526
-
1527
- IF NOT TG_ARGV[0]::boolean IS DISTINCT FROM 'f'::boolean THEN
1528
- audit_row.client_query = NULL;
1529
- END IF;
1530
-
1531
- IF ((TG_ARGV[1] IS NOT NULL) AND (TG_LEVEL = 'ROW')) THEN
1532
- pk_val_query = 'SELECT $1.' || quote_ident(TG_ARGV[1]::text);
1533
-
1534
- IF (TG_OP IS DISTINCT FROM 'DELETE') THEN
1535
- EXECUTE pk_val_query INTO audit_row.row_id USING NEW;
1536
- END IF;
1537
-
1538
- IF audit_row.row_id IS NULL THEN
1539
- EXECUTE pk_val_query INTO audit_row.row_id USING OLD;
1540
- END IF;
1541
- END IF;
1542
-
1543
- IF TG_ARGV[2] IS NOT NULL THEN
1544
- excluded_cols = TG_ARGV[2]::text[];
1545
- END IF;
1546
-
1547
-
1548
-
1549
- IF (TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW') THEN
1550
- audit_row.row_data = hstore(OLD.*) - excluded_cols;
1551
- audit_row.changed_fields = (hstore(NEW.*) - audit_row.row_data) - excluded_cols;
1552
- IF audit_row.changed_fields = hstore('') THEN
1553
- -- All changed fields are ignored. Skip this update.
1554
- RETURN NULL;
1555
- END IF;
1556
- ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
1557
- audit_row.row_data = hstore(OLD.*) - excluded_cols;
1558
- ELSIF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
1559
- audit_row.row_data = hstore(NEW.*) - excluded_cols;
1560
- ELSIF (TG_LEVEL = 'STATEMENT' AND TG_OP IN ('INSERT','UPDATE','DELETE','TRUNCATE')) THEN
1561
- audit_row.statement_only = 't';
1562
- ELSE
1563
- RAISE EXCEPTION '[auditing.if_modified_func] - Trigger func added as trigger for unhandled case: %, %',TG_OP, TG_LEVEL;
1564
- RETURN NULL;
1565
- END IF;
1566
-
1567
- -- inject app_user data into audit
1568
- BEGIN
1569
- PERFORM
1570
- n.nspname, c.relname
1571
- FROM
1572
- pg_catalog.pg_class c
1573
- LEFT JOIN
1574
- pg_catalog.pg_namespace n
1575
- ON n.oid = c.relnamespace
1576
- WHERE
1577
- n.nspname like 'pg_temp_%'
1578
- AND
1579
- c.relname = '_app_user';
1580
-
1581
- IF FOUND THEN
1582
- FOR user_row IN SELECT * FROM _app_user LIMIT 1 LOOP
1583
- audit_row.app_user_id = user_row.user_id;
1584
- audit_row.app_user_type = user_row.user_type;
1585
- audit_row.app_ip_address = user_row.ip_address;
1586
- END LOOP;
1587
- END IF;
1588
- END;
1589
- -- end app_user data
1590
-
1591
- INSERT INTO auditing.logged_actions VALUES (audit_row.*);
1592
- RETURN NULL;
1593
- END;
1594
- $$
1595
- LANGUAGE plpgsql
1596
- SECURITY DEFINER
1597
- SET search_path = pg_catalog, public;
1598
-
1599
-
1600
- COMMENT ON FUNCTION auditing.if_modified_func() IS
1601
- $$
1602
- Track changes to a table at the statement and/or row level.
1603
-
1604
- Optional parameters to trigger in CREATE TRIGGER call:
1605
-
1606
- param 0: boolean, whether to log the query text. Default 't'.
1607
-
1608
- param 1: text, primary_key_column of audited table if bigint.
1609
-
1610
- param 2: text[], columns to ignore in updates. Default [].
1611
-
1612
- Updates to ignored cols are omitted from changed_fields.
1613
-
1614
- Updates with only ignored cols changed are not inserted
1615
- into the audit log.
1616
-
1617
- Almost all the processing work is still done for updates
1618
- that ignored. If you need to save the load, you need to use
1619
- WHEN clause on the trigger instead.
1620
-
1621
- No warning or error is issued if ignored_cols contains columns
1622
- that do not exist in the target table. This lets you specify
1623
- a standard set of ignored columns.
1624
-
1625
- There is no parameter to disable logging of values. Add this trigger as
1626
- a 'FOR EACH STATEMENT' rather than 'FOR EACH ROW' trigger if you do not
1627
- want to log row values.
1628
-
1629
- Note that the user name logged is the login role for the session. The audit trigger
1630
- cannot obtain the active role because it is reset by the SECURITY DEFINER invocation
1631
- of the audit trigger its self.
1632
- $$;
1633
-
1634
-
1635
- CREATE OR REPLACE FUNCTION auditing.get_primary_key_column(target_table text)
1636
- RETURNS text AS
1637
- $$
1638
- DECLARE
1639
- _pk_query_text text;
1640
- _pk_column_name text;
1641
- BEGIN
1642
- _pk_query_text = 'SELECT a.attname ' ||
1643
- 'FROM pg_index i ' ||
1644
- 'JOIN pg_attribute a ON a.attrelid = i.indrelid ' ||
1645
- ' AND a.attnum = ANY(i.indkey) ' ||
1646
- 'WHERE i.indrelid = ' || quote_literal(target_table::TEXT) || '::regclass ' ||
1647
- 'AND i.indisprimary ' ||
1648
- 'AND format_type(a.atttypid, a.atttypmod) = ' || quote_literal('bigint'::TEXT) ||
1649
- 'LIMIT 1';
1650
-
1651
- EXECUTE _pk_query_text INTO _pk_column_name;
1652
- raise notice 'Value %', _pk_column_name;
1653
- return _pk_column_name;
1654
- END;
1655
- $$
1656
- LANGUAGE plpgsql;
1657
-
1658
- COMMENT ON FUNCTION auditing.get_primary_key_column(text) IS
1659
- $$
1660
- Get primary key column name if single PK and type bigint.
1661
-
1662
- Arguments:
1663
- target_table: Table name, schema qualified if not on search_path
1664
- $$;
1665
-
1666
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean, ignored_cols text[])
1667
- RETURNS void AS
1668
- $$
1669
- DECLARE
1670
- stm_targets text = 'INSERT OR UPDATE OR DELETE OR TRUNCATE';
1671
- _q_txt text;
1672
- _pk_column_name text;
1673
- _pk_column_snip text;
1674
- _ignored_cols_snip text = '';
1675
- BEGIN
1676
- EXECUTE 'DROP TRIGGER IF EXISTS audit_trigger_row ON ' || quote_ident(target_table::TEXT);
1677
- EXECUTE 'DROP TRIGGER IF EXISTS audit_trigger_stm ON ' || quote_ident(target_table::TEXT);
1678
-
1679
- IF audit_rows THEN
1680
- _pk_column_name = auditing.get_primary_key_column(target_table::TEXT);
1681
-
1682
- IF _pk_column_name IS NOT NULL THEN
1683
- _pk_column_snip = ', ' || quote_literal(_pk_column_name);
1684
- ELSE
1685
- _pk_column_snip = ', NULL';
1686
- END IF;
1687
-
1688
- IF array_length(ignored_cols,1) > 0 THEN
1689
- _ignored_cols_snip = ', ' || quote_literal(ignored_cols);
1690
- END IF;
1691
- _q_txt = 'CREATE TRIGGER audit_trigger_row AFTER INSERT OR UPDATE OR DELETE ON ' ||
1692
- quote_ident(target_table::TEXT) ||
1693
- ' FOR EACH ROW EXECUTE PROCEDURE auditing.if_modified_func(' ||
1694
- quote_literal(audit_query_text) || _pk_column_snip || _ignored_cols_snip || ');';
1695
- RAISE NOTICE '%',_q_txt;
1696
- EXECUTE _q_txt;
1697
- stm_targets = 'TRUNCATE';
1698
- ELSE
1699
- END IF;
1700
-
1701
- _q_txt = 'CREATE TRIGGER audit_trigger_stm AFTER ' || stm_targets || ' ON ' ||
1702
- target_table ||
1703
- ' FOR EACH STATEMENT EXECUTE PROCEDURE auditing.if_modified_func('||
1704
- quote_literal(audit_query_text) || ');';
1705
- RAISE NOTICE '%',_q_txt;
1706
- EXECUTE _q_txt;
1707
-
1708
- END;
1709
- $$
1710
- LANGUAGE plpgsql;
1711
-
1712
- COMMENT ON FUNCTION auditing.audit_table(regclass, boolean, boolean, text[]) IS
1713
- $$
1714
- Add auditing support to a table.
1715
-
1716
- Arguments:
1717
- target_table: Table name, schema qualified if not on search_path
1718
- audit_rows: Record each row change, or only audit at a statement level
1719
- audit_query_text: Record the text of the client query that triggered the audit event?
1720
- ignored_cols: Columns to exclude from update diffs, ignore updates that change only ignored cols.
1721
- $$;
1722
-
1723
- -- Pg doesn't allow variadic calls with 0 params, so provide a wrapper
1724
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass, audit_rows boolean, audit_query_text boolean)
1725
- RETURNS void AS
1726
- $$
1727
- SELECT auditing.audit_table($1, $2, $3, ARRAY[]::text[]);
1728
- $$
1729
- LANGUAGE SQL;
1730
-
1731
- -- And provide a convenience call wrapper for the simplest case
1732
- -- of row-level logging with no excluded cols and query logging enabled.
1733
- --
1734
- CREATE OR REPLACE FUNCTION auditing.audit_table(target_table regclass)
1735
- RETURNS void AS
1736
- $$
1737
- SELECT auditing.audit_table($1, BOOLEAN 't', BOOLEAN 't');
1738
- $$
1739
- LANGUAGE SQL;
1740
-
1741
- COMMENT ON FUNCTION auditing.audit_table(regclass) IS
1742
- $$
1743
- Add auditing support to the given table. Row-level changes will be logged with full client query text. No cols are ignored.
1744
- $$;
1745
- 
1746
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:14
1747
-  (0.2ms)  CREATE or REPLACE FUNCTION public.temp_table_exists( varchar)
1748
- RETURNS pg_catalog.bool AS
1749
- $$
1750
- BEGIN
1751
- /* check the table exist in database and is visible*/
1752
- PERFORM n.nspname, c.relname
1753
- FROM pg_catalog.pg_class c
1754
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
1755
- WHERE n.nspname LIKE 'pg_temp_%' AND pg_catalog.pg_table_is_visible(c.oid)
1756
- AND relname = $1;
1757
-
1758
- IF FOUND THEN
1759
- RETURN TRUE;
1760
- ELSE
1761
- RETURN FALSE;
1762
- END IF;
1763
-
1764
- END;
1765
- $$
1766
- LANGUAGE 'plpgsql' VOLATILE
1767
- 
1768
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:16
1769
-  (0.4ms)  CREATE OR REPLACE FUNCTION hash_password(password text)
1770
- RETURNS text AS
1771
- $BODY$
1772
- BEGIN
1773
- password = crypt(password, gen_salt('bf', 8));
1774
-
1775
- RETURN password;
1776
- END;
1777
- $BODY$
1778
-
1779
- LANGUAGE plpgsql;
1780
- 
1781
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:39
1782
-  (0.2ms)  CREATE OR REPLACE FUNCTION validate_email(email text)
1783
- RETURNS text AS
1784
- $BODY$
1785
- BEGIN
1786
- IF email IS NOT NULL THEN
1787
- IF email !~* '\A[^@\s\;]+@[^@\s\;]+\.[^@\s\;]+\Z' THEN
1788
- RAISE EXCEPTION 'Invalid E-mail format %', email
1789
- USING HINT = 'Please check your E-mail format.';
1790
- END IF ;
1791
- email = lower(email);
1792
- END IF ;
1793
-
1794
- RETURN email;
1795
- END;
1796
- $BODY$
1797
- LANGUAGE plpgsql;
1798
- 
1799
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:53
1800
-  (0.2ms)  CREATE OR REPLACE FUNCTION valid_email_trigger()
1801
- RETURNS TRIGGER AS
1802
- $BODY$
1803
- BEGIN
1804
- NEW.email = validate_email(NEW.email);
1805
-
1806
- RETURN NEW;
1807
- END;
1808
- $BODY$
1809
- LANGUAGE plpgsql;
1810
- 
1811
- ↳ /home/samps/gems/better_record/db/migrate/20180725160802_create_better_record_db_functions.rb:72
1812
- ActiveRecord::SchemaMigration Create (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20180725160802"]]
1813
- ↳ bin/rails:14
1814
-  (4.6ms) COMMIT
1815
- ↳ bin/rails:14
1816
- Migrating to CreateBetterRecordTableSizes (20180725201614)
1817
-  (0.2ms) BEGIN
1818
- ↳ bin/rails:14
1819
-  (1.4ms) CREATE TABLE "auditing"."table_sizes" ("oid" bigint, "schema" character varying, "name" character varying, "apx_row_count" float, "total_bytes" bigint, "idx_bytes" bigint, "toast_bytes" bigint, "tbl_bytes" bigint, "total" text, "idx" text, "toast" text, "tbl" text)
1820
- ↳ /home/samps/gems/better_record/db/migrate/20180725201614_create_better_record_table_sizes.rb:3
1821
-  (1.0ms) ALTER TABLE auditing.table_sizes ADD PRIMARY KEY (oid);
1822
- ↳ /home/samps/gems/better_record/db/migrate/20180725201614_create_better_record_table_sizes.rb:20
1823
- ActiveRecord::SchemaMigration Create (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20180725201614"]]
1824
- ↳ bin/rails:14
1825
-  (1.0ms) COMMIT
1826
- ↳ bin/rails:14
1827
- ActiveRecord::InternalMetadata Load (0.2ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
1828
- ↳ bin/rails:14
1829
-  (0.1ms) BEGIN
1830
- ↳ bin/rails:14
1831
- ActiveRecord::InternalMetadata Create (0.2ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", "2018-07-25 22:41:52.675805"], ["updated_at", "2018-07-25 22:41:52.675805"]]
1832
- ↳ bin/rails:14
1833
-  (0.8ms) COMMIT
1834
- ↳ bin/rails:14
1835
-  (0.1ms) SELECT pg_advisory_unlock(3614663923613387715)
1836
- ↳ bin/rails:14
1837
-  (0.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1838
- ↳ bin/rails:14
1839
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1840
- ↳ bin/rails:14
1841
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
1842
- ↳ bin/rails:14
1843
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1844
- ↳ bin/rails:14
1845
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
1846
- ↳ bin/rails:14
1847
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
1848
- ↳ bin/rails:14
1849
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
1850
- ↳ bin/rails:14
1851
-  (108.1ms) DROP DATABASE IF EXISTS "better_record_test"
1852
- ↳ bin/rails:14
1853
-  (254.2ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
1854
- ↳ bin/rails:14
1855
- ActiveRecord::InternalMetadata Load (0.8ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
1856
- ↳ bin/rails:14
1857
-  (0.4ms) BEGIN
1858
- ↳ bin/rails:14
1859
- ActiveRecord::InternalMetadata Create (0.8ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-25 22:42:03.569956"], ["updated_at", "2018-07-25 22:42:03.569956"]]
1860
- ↳ bin/rails:14
1861
-  (1.2ms) COMMIT
1862
- ↳ bin/rails:14
1863
-  (2.6ms)  BEGIN WORK;
1864
- LOCK TABLE auditing.table_sizes;
1865
- TRUNCATE TABLE auditing.table_sizes;
1866
- INSERT INTO auditing.table_sizes (
1867
- SELECT
1868
- *,
1869
- pg_size_pretty(total_bytes) AS total,
1870
- pg_size_pretty(idx_bytes) AS idx,
1871
- pg_size_pretty(toast_bytes) AS toast,
1872
- pg_size_pretty(tbl_bytes) AS tbl,
1873
- NOW()
1874
- FROM (
1875
- SELECT
1876
- *,
1877
- total_bytes - idx_bytes - COALESCE(toast_bytes,0) AS tbl_bytes
1878
- FROM (
1879
- SELECT c.oid,nspname AS schema, relname AS name
1880
- , c.reltuples AS row_estimate
1881
- , pg_total_relation_size(c.oid) AS total_bytes
1882
- , pg_indexes_size(c.oid) AS idx_bytes
1883
- , pg_total_relation_size(reltoastrelid) AS toast_bytes
1884
- FROM pg_class c
1885
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
1886
- WHERE relkind = 'r'
1887
- ) table_sizes
1888
- ) table_sizes
1889
- );
1890
- COMMIT WORK;
1891
- 
1892
-  (0.8ms)  BEGIN WORK;
1893
- LOCK TABLE auditing.table_sizes;
1894
- TRUNCATE TABLE auditing.table_sizes;
1895
- INSERT INTO auditing.table_sizes (
1896
- SELECT
1897
- *,
1898
- pg_size_pretty(total_bytes) AS total,
1899
- pg_size_pretty(idx_bytes) AS idx,
1900
- pg_size_pretty(toast_bytes) AS toast,
1901
- pg_size_pretty(tbl_bytes) AS tbl,
1902
- FROM (
1903
- SELECT
1904
- *,
1905
- total_bytes - idx_bytes - COALESCE(toast_bytes,0) AS tbl_bytes
1906
- FROM (
1907
- SELECT c.oid,nspname AS schema, relname AS name
1908
- , c.reltuples AS row_estimate
1909
- , pg_total_relation_size(c.oid) AS total_bytes
1910
- , pg_indexes_size(c.oid) AS idx_bytes
1911
- , pg_total_relation_size(reltoastrelid) AS toast_bytes
1912
- FROM pg_class c
1913
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
1914
- WHERE relkind = 'r'
1915
- ) table_sizes
1916
- ) table_sizes
1917
- );
1918
- COMMIT WORK;
1919
- 
1920
-  (34.0ms)  BEGIN WORK;
1921
- LOCK TABLE auditing.table_sizes;
1922
- TRUNCATE TABLE auditing.table_sizes;
1923
- INSERT INTO auditing.table_sizes (
1924
- SELECT
1925
- *,
1926
- pg_size_pretty(total_bytes) AS total,
1927
- pg_size_pretty(idx_bytes) AS idx,
1928
- pg_size_pretty(toast_bytes) AS toast,
1929
- pg_size_pretty(tbl_bytes) AS tbl
1930
- FROM (
1931
- SELECT
1932
- *,
1933
- total_bytes - idx_bytes - COALESCE(toast_bytes,0) AS tbl_bytes
1934
- FROM (
1935
- SELECT c.oid,nspname AS schema, relname AS name
1936
- , c.reltuples AS row_estimate
1937
- , pg_total_relation_size(c.oid) AS total_bytes
1938
- , pg_indexes_size(c.oid) AS idx_bytes
1939
- , pg_total_relation_size(reltoastrelid) AS toast_bytes
1940
- FROM pg_class c
1941
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
1942
- WHERE relkind = 'r'
1943
- ) table_sizes
1944
- ) table_sizes
1945
- );
1946
- COMMIT WORK;
1947
- 
1948
- BetterRecord::TableSize Load (0.7ms) SELECT "auditing"."table_sizes".* FROM "auditing"."table_sizes" WHERE "auditing"."table_sizes"."schema" = $1 [["schema", "public"]]
1949
-  (6.6ms)  BEGIN WORK;
1950
- LOCK TABLE auditing.table_sizes;
1951
- TRUNCATE TABLE auditing.table_sizes;
1952
- INSERT INTO auditing.table_sizes (
1953
- SELECT
1954
- *,
1955
- pg_size_pretty(total_bytes) AS total,
1956
- pg_size_pretty(idx_bytes) AS idx,
1957
- pg_size_pretty(toast_bytes) AS toast,
1958
- pg_size_pretty(tbl_bytes) AS tbl
1959
- FROM (
1960
- SELECT
1961
- *,
1962
- total_bytes - idx_bytes - COALESCE(toast_bytes,0) AS tbl_bytes
1963
- FROM (
1964
- SELECT c.oid,nspname AS schema, relname AS name
1965
- , c.reltuples AS row_estimate
1966
- , pg_total_relation_size(c.oid) AS total_bytes
1967
- , pg_indexes_size(c.oid) AS idx_bytes
1968
- , pg_total_relation_size(reltoastrelid) AS toast_bytes
1969
- FROM pg_class c
1970
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
1971
- WHERE relkind = 'r'
1972
- ) table_sizes
1973
- ) table_sizes
1974
- );
1975
- COMMIT WORK;
1976
- 
1977
- BetterRecord::TableSize Load (0.2ms) SELECT "auditing"."table_sizes".* FROM "auditing"."table_sizes" WHERE "auditing"."table_sizes"."schema" = $1 ORDER BY "auditing"."table_sizes"."oid" ASC LIMIT $2 [["schema", "public"], ["LIMIT", 1]]
1978
- BetterRecord::TableSize Load (0.2ms) SELECT "auditing"."table_sizes".* FROM "auditing"."table_sizes" WHERE "auditing"."table_sizes"."schema" = $1 ORDER BY "auditing"."table_sizes"."oid" ASC LIMIT $2 [["schema", "public"], ["LIMIT", 1]]
1979
-  (5.0ms)  BEGIN WORK;
1980
- LOCK TABLE auditing.table_sizes;
1981
- TRUNCATE TABLE auditing.table_sizes;
1982
- INSERT INTO auditing.table_sizes (
1983
- SELECT
1984
- *,
1985
- pg_size_pretty(total_bytes) AS total,
1986
- pg_size_pretty(idx_bytes) AS idx,
1987
- pg_size_pretty(toast_bytes) AS toast,
1988
- pg_size_pretty(tbl_bytes) AS tbl
1989
- FROM (
1990
- SELECT
1991
- *,
1992
- total_bytes - idx_bytes - COALESCE(toast_bytes,0) AS tbl_bytes
1993
- FROM (
1994
- SELECT c.oid,nspname AS schema, relname AS name
1995
- , c.reltuples AS row_estimate
1996
- , pg_total_relation_size(c.oid) AS total_bytes
1997
- , pg_indexes_size(c.oid) AS idx_bytes
1998
- , pg_total_relation_size(reltoastrelid) AS toast_bytes
1999
- FROM pg_class c
2000
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
2001
- WHERE relkind = 'r'
2002
- ) table_sizes
2003
- ) table_sizes
2004
- );
2005
- COMMIT WORK;
2006
- 
2007
- BetterRecord::TableSize Load (0.2ms) SELECT "auditing"."table_sizes".* FROM "auditing"."table_sizes" WHERE "auditing"."table_sizes"."schema" = $1 ORDER BY "auditing"."table_sizes"."oid" ASC LIMIT $2 [["schema", "public"], ["LIMIT", 1]]
2008
- BetterRecord::TableSize Load (0.2ms) SELECT "auditing"."table_sizes".* FROM "auditing"."table_sizes" WHERE "auditing"."table_sizes"."schema" = $1 ORDER BY "auditing"."table_sizes"."oid" ASC LIMIT $2 [["schema", "public"], ["LIMIT", 1]]
2009
-  (4.9ms)  BEGIN WORK;
2010
- LOCK TABLE auditing.table_sizes;
2011
- TRUNCATE TABLE auditing.table_sizes;
2012
- INSERT INTO auditing.table_sizes (
2013
- SELECT
2014
- *,
2015
- pg_size_pretty(total_bytes) AS total,
2016
- pg_size_pretty(idx_bytes) AS idx,
2017
- pg_size_pretty(toast_bytes) AS toast,
2018
- pg_size_pretty(tbl_bytes) AS tbl
2019
- FROM (
2020
- SELECT
2021
- *,
2022
- total_bytes - idx_bytes - COALESCE(toast_bytes,0) AS tbl_bytes
2023
- FROM (
2024
- SELECT c.oid,nspname AS schema, relname AS name
2025
- , c.reltuples AS row_estimate
2026
- , pg_total_relation_size(c.oid) AS total_bytes
2027
- , pg_indexes_size(c.oid) AS idx_bytes
2028
- , pg_total_relation_size(reltoastrelid) AS toast_bytes
2029
- FROM pg_class c
2030
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
2031
- WHERE relkind = 'r'
2032
- ) table_sizes
2033
- ) table_sizes
2034
- );
2035
- COMMIT WORK;
2036
- 
2037
- BetterRecord::TableSize Load (0.2ms) SELECT "auditing"."table_sizes".* FROM "auditing"."table_sizes" WHERE "auditing"."table_sizes"."schema" = $1 ORDER BY "auditing"."table_sizes"."oid" ASC LIMIT $2 [["schema", "public"], ["LIMIT", 1]]
2038
-  (0.2ms) SELECT COUNT(*) FROM "auditing"."table_sizes" WHERE "auditing"."table_sizes"."schema" = $1 [["schema", "public"]]
2039
- BetterRecord::TableSize Load (0.1ms) SELECT "auditing"."table_sizes".* FROM "auditing"."table_sizes" WHERE "auditing"."table_sizes"."schema" = $1 [["schema", "public"]]
2040
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2041
- ↳ bin/rails:14
2042
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2043
- ↳ bin/rails:14
2044
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2045
- ↳ bin/rails:14
2046
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2047
- ↳ bin/rails:14
2048
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2049
- ↳ bin/rails:14
2050
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2051
- ↳ bin/rails:14
2052
-  (108.5ms) DROP DATABASE IF EXISTS "better_record_test"
2053
- ↳ bin/rails:14
2054
-  (258.1ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2055
- ↳ bin/rails:14
2056
- ActiveRecord::InternalMetadata Load (0.9ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2057
- ↳ bin/rails:14
2058
-  (0.3ms) BEGIN
2059
- ↳ bin/rails:14
2060
- ActiveRecord::InternalMetadata Create (0.8ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:03:33.537896"], ["updated_at", "2018-07-26 00:03:33.537896"]]
2061
- ↳ bin/rails:14
2062
-  (1.2ms) COMMIT
2063
- ↳ bin/rails:14
2064
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2065
- ↳ bin/rails:14
2066
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2067
- ↳ bin/rails:14
2068
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2069
- ↳ bin/rails:14
2070
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2071
- ↳ bin/rails:14
2072
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2073
- ↳ bin/rails:14
2074
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2075
- ↳ bin/rails:14
2076
-  (108.2ms) DROP DATABASE IF EXISTS "better_record_test"
2077
- ↳ bin/rails:14
2078
-  (256.2ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2079
- ↳ bin/rails:14
2080
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2081
- ↳ bin/rails:14
2082
-  (0.1ms) BEGIN
2083
- ↳ bin/rails:14
2084
- ActiveRecord::InternalMetadata Create (0.4ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:04:11.680554"], ["updated_at", "2018-07-26 00:04:11.680554"]]
2085
- ↳ bin/rails:14
2086
-  (0.9ms) COMMIT
2087
- ↳ bin/rails:14
2088
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2089
- ↳ bin/rails:14
2090
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2091
- ↳ bin/rails:14
2092
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2093
- ↳ bin/rails:14
2094
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2095
- ↳ bin/rails:14
2096
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2097
- ↳ bin/rails:14
2098
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2099
- ↳ bin/rails:14
2100
-  (114.8ms) DROP DATABASE IF EXISTS "better_record_test"
2101
- ↳ bin/rails:14
2102
-  (259.2ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2103
- ↳ bin/rails:14
2104
- ActiveRecord::InternalMetadata Load (0.9ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2105
- ↳ bin/rails:14
2106
-  (0.4ms) BEGIN
2107
- ↳ bin/rails:14
2108
- ActiveRecord::InternalMetadata Create (0.9ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:05:30.362239"], ["updated_at", "2018-07-26 00:05:30.362239"]]
2109
- ↳ bin/rails:14
2110
-  (1.1ms) COMMIT
2111
- ↳ bin/rails:14
2112
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2113
- ↳ bin/rails:14
2114
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2115
- ↳ bin/rails:14
2116
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2117
- ↳ bin/rails:14
2118
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2119
- ↳ bin/rails:14
2120
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2121
- ↳ bin/rails:14
2122
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2123
- ↳ bin/rails:14
2124
-  (108.5ms) DROP DATABASE IF EXISTS "better_record_test"
2125
- ↳ bin/rails:14
2126
-  (256.9ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2127
- ↳ bin/rails:14
2128
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2129
- ↳ bin/rails:14
2130
-  (0.1ms) BEGIN
2131
- ↳ bin/rails:14
2132
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:08:30.287165"], ["updated_at", "2018-07-26 00:08:30.287165"]]
2133
- ↳ bin/rails:14
2134
-  (0.8ms) COMMIT
2135
- ↳ bin/rails:14
2136
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2137
- ↳ bin/rails:14
2138
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2139
- ↳ bin/rails:14
2140
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2141
- ↳ bin/rails:14
2142
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2143
- ↳ bin/rails:14
2144
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2145
- ↳ bin/rails:14
2146
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2147
- ↳ bin/rails:14
2148
-  (114.8ms) DROP DATABASE IF EXISTS "better_record_test"
2149
- ↳ bin/rails:14
2150
-  (257.4ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2151
- ↳ bin/rails:14
2152
- ActiveRecord::InternalMetadata Load (0.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2153
- ↳ bin/rails:14
2154
-  (0.2ms) BEGIN
2155
- ↳ bin/rails:14
2156
- ActiveRecord::InternalMetadata Create (0.5ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:08:57.767383"], ["updated_at", "2018-07-26 00:08:57.767383"]]
2157
- ↳ bin/rails:14
2158
-  (1.0ms) COMMIT
2159
- ↳ bin/rails:14
2160
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2161
- ↳ bin/rails:14
2162
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2163
- ↳ bin/rails:14
2164
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2165
- ↳ bin/rails:14
2166
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2167
- ↳ bin/rails:14
2168
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2169
- ↳ bin/rails:14
2170
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2171
- ↳ bin/rails:14
2172
-  (117.5ms) DROP DATABASE IF EXISTS "better_record_test"
2173
- ↳ bin/rails:14
2174
-  (255.9ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2175
- ↳ bin/rails:14
2176
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2177
- ↳ bin/rails:14
2178
-  (0.5ms) BEGIN
2179
- ↳ bin/rails:14
2180
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:20:58.093189"], ["updated_at", "2018-07-26 00:20:58.093189"]]
2181
- ↳ bin/rails:14
2182
-  (0.9ms) COMMIT
2183
- ↳ bin/rails:14
2184
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2185
- ↳ bin/rails:14
2186
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2187
- ↳ bin/rails:14
2188
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2189
- ↳ bin/rails:14
2190
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2191
- ↳ bin/rails:14
2192
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2193
- ↳ bin/rails:14
2194
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2195
- ↳ bin/rails:14
2196
-  (114.7ms) DROP DATABASE IF EXISTS "better_record_test"
2197
- ↳ bin/rails:14
2198
-  (241.9ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2199
- ↳ bin/rails:14
2200
- ActiveRecord::InternalMetadata Load (0.8ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2201
- ↳ bin/rails:14
2202
-  (0.3ms) BEGIN
2203
- ↳ bin/rails:14
2204
- ActiveRecord::InternalMetadata Create (0.9ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:21:28.446117"], ["updated_at", "2018-07-26 00:21:28.446117"]]
2205
- ↳ bin/rails:14
2206
-  (1.1ms) COMMIT
2207
- ↳ bin/rails:14
2208
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2209
- ↳ bin/rails:14
2210
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2211
- ↳ bin/rails:14
2212
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2213
- ↳ bin/rails:14
2214
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2215
- ↳ bin/rails:14
2216
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2217
- ↳ bin/rails:14
2218
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2219
- ↳ bin/rails:14
2220
-  (108.1ms) DROP DATABASE IF EXISTS "better_record_test"
2221
- ↳ bin/rails:14
2222
-  (256.9ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2223
- ↳ bin/rails:14
2224
- ActiveRecord::InternalMetadata Load (0.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2225
- ↳ bin/rails:14
2226
-  (0.2ms) BEGIN
2227
- ↳ bin/rails:14
2228
- ActiveRecord::InternalMetadata Create (0.5ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:22:55.876708"], ["updated_at", "2018-07-26 00:22:55.876708"]]
2229
- ↳ bin/rails:14
2230
-  (0.9ms) COMMIT
2231
- ↳ bin/rails:14
2232
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2233
- ↳ bin/rails:14
2234
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2235
- ↳ bin/rails:14
2236
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2237
- ↳ bin/rails:14
2238
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2239
- ↳ bin/rails:14
2240
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2241
- ↳ bin/rails:14
2242
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2243
- ↳ bin/rails:14
2244
-  (108.2ms) DROP DATABASE IF EXISTS "better_record_test"
2245
- ↳ bin/rails:14
2246
-  (255.2ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2247
- ↳ bin/rails:14
2248
- ActiveRecord::InternalMetadata Load (0.7ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2249
- ↳ bin/rails:14
2250
-  (0.3ms) BEGIN
2251
- ↳ bin/rails:14
2252
- ActiveRecord::InternalMetadata Create (0.7ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:23:23.836084"], ["updated_at", "2018-07-26 00:23:23.836084"]]
2253
- ↳ bin/rails:14
2254
-  (1.2ms) COMMIT
2255
- ↳ bin/rails:14
2256
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2257
- ↳ bin/rails:14
2258
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2259
- ↳ bin/rails:14
2260
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2261
- ↳ bin/rails:14
2262
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2263
- ↳ bin/rails:14
2264
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2265
- ↳ bin/rails:14
2266
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2267
- ↳ bin/rails:14
2268
-  (108.6ms) DROP DATABASE IF EXISTS "better_record_test"
2269
- ↳ bin/rails:14
2270
-  (255.7ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2271
- ↳ bin/rails:14
2272
- ActiveRecord::InternalMetadata Load (0.8ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2273
- ↳ bin/rails:14
2274
-  (0.4ms) BEGIN
2275
- ↳ bin/rails:14
2276
- ActiveRecord::InternalMetadata Create (0.9ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:23:59.424879"], ["updated_at", "2018-07-26 00:23:59.424879"]]
2277
- ↳ bin/rails:14
2278
-  (1.1ms) COMMIT
2279
- ↳ bin/rails:14
2280
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2281
- ↳ bin/rails:14
2282
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2283
- ↳ bin/rails:14
2284
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2285
- ↳ bin/rails:14
2286
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2287
- ↳ bin/rails:14
2288
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2289
- ↳ bin/rails:14
2290
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2291
- ↳ bin/rails:14
2292
-  (108.7ms) DROP DATABASE IF EXISTS "better_record_test"
2293
- ↳ bin/rails:14
2294
-  (256.4ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2295
- ↳ bin/rails:14
2296
- ActiveRecord::InternalMetadata Load (0.6ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2297
- ↳ bin/rails:14
2298
-  (0.4ms) BEGIN
2299
- ↳ bin/rails:14
2300
- ActiveRecord::InternalMetadata Create (0.9ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:24:44.202978"], ["updated_at", "2018-07-26 00:24:44.202978"]]
2301
- ↳ bin/rails:14
2302
-  (1.0ms) COMMIT
2303
- ↳ bin/rails:14
2304
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2305
- ↳ bin/rails:14
2306
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2307
- ↳ bin/rails:14
2308
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2309
- ↳ bin/rails:14
2310
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2311
- ↳ bin/rails:14
2312
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2313
- ↳ bin/rails:14
2314
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2315
- ↳ bin/rails:14
2316
-  (108.6ms) DROP DATABASE IF EXISTS "better_record_test"
2317
- ↳ bin/rails:14
2318
-  (255.7ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2319
- ↳ bin/rails:14
2320
- ActiveRecord::InternalMetadata Load (0.8ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2321
- ↳ bin/rails:14
2322
-  (0.3ms) BEGIN
2323
- ↳ bin/rails:14
2324
- ActiveRecord::InternalMetadata Create (0.8ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:25:15.855816"], ["updated_at", "2018-07-26 00:25:15.855816"]]
2325
- ↳ bin/rails:14
2326
-  (1.0ms) COMMIT
2327
- ↳ bin/rails:14
2328
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2329
- ↳ bin/rails:14
2330
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2331
- ↳ bin/rails:14
2332
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2333
- ↳ bin/rails:14
2334
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2335
- ↳ bin/rails:14
2336
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2337
- ↳ bin/rails:14
2338
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2339
- ↳ bin/rails:14
2340
-  (108.5ms) DROP DATABASE IF EXISTS "better_record_test"
2341
- ↳ bin/rails:14
2342
-  (255.8ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2343
- ↳ bin/rails:14
2344
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2345
- ↳ bin/rails:14
2346
-  (0.1ms) BEGIN
2347
- ↳ bin/rails:14
2348
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:25:50.655973"], ["updated_at", "2018-07-26 00:25:50.655973"]]
2349
- ↳ bin/rails:14
2350
-  (0.7ms) COMMIT
2351
- ↳ bin/rails:14
2352
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2353
- ↳ bin/rails:14
2354
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2355
- ↳ bin/rails:14
2356
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2357
- ↳ bin/rails:14
2358
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2359
- ↳ bin/rails:14
2360
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2361
- ↳ bin/rails:14
2362
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2363
- ↳ bin/rails:14
2364
-  (108.8ms) DROP DATABASE IF EXISTS "better_record_test"
2365
- ↳ bin/rails:14
2366
-  (258.7ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2367
- ↳ bin/rails:14
2368
- ActiveRecord::InternalMetadata Load (0.6ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2369
- ↳ bin/rails:14
2370
-  (0.3ms) BEGIN
2371
- ↳ bin/rails:14
2372
- ActiveRecord::InternalMetadata Create (0.7ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:28:04.003975"], ["updated_at", "2018-07-26 00:28:04.003975"]]
2373
- ↳ bin/rails:14
2374
-  (1.1ms) COMMIT
2375
- ↳ bin/rails:14
2376
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2377
- ↳ bin/rails:14
2378
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2379
- ↳ bin/rails:14
2380
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2381
- ↳ bin/rails:14
2382
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2383
- ↳ bin/rails:14
2384
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2385
- ↳ bin/rails:14
2386
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2387
- ↳ bin/rails:14
2388
-  (108.3ms) DROP DATABASE IF EXISTS "better_record_test"
2389
- ↳ bin/rails:14
2390
-  (257.1ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2391
- ↳ bin/rails:14
2392
- ActiveRecord::InternalMetadata Load (0.8ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2393
- ↳ bin/rails:14
2394
-  (0.4ms) BEGIN
2395
- ↳ bin/rails:14
2396
- ActiveRecord::InternalMetadata Create (0.9ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:29:07.035084"], ["updated_at", "2018-07-26 00:29:07.035084"]]
2397
- ↳ bin/rails:14
2398
-  (1.1ms) COMMIT
2399
- ↳ bin/rails:14
2400
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2401
- ↳ bin/rails:14
2402
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2403
- ↳ bin/rails:14
2404
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2405
- ↳ bin/rails:14
2406
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2407
- ↳ bin/rails:14
2408
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2409
- ↳ bin/rails:14
2410
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2411
- ↳ bin/rails:14
2412
-  (108.5ms) DROP DATABASE IF EXISTS "better_record_test"
2413
- ↳ bin/rails:14
2414
-  (240.7ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2415
- ↳ bin/rails:14
2416
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2417
- ↳ bin/rails:14
2418
-  (0.1ms) BEGIN
2419
- ↳ bin/rails:14
2420
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:29:24.246496"], ["updated_at", "2018-07-26 00:29:24.246496"]]
2421
- ↳ bin/rails:14
2422
-  (0.8ms) COMMIT
2423
- ↳ bin/rails:14
2424
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2425
- ↳ bin/rails:14
2426
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2427
- ↳ bin/rails:14
2428
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2429
- ↳ bin/rails:14
2430
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2431
- ↳ bin/rails:14
2432
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2433
- ↳ bin/rails:14
2434
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2435
- ↳ bin/rails:14
2436
-  (108.6ms) DROP DATABASE IF EXISTS "better_record_test"
2437
- ↳ bin/rails:14
2438
-  (257.3ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2439
- ↳ bin/rails:14
2440
- ActiveRecord::InternalMetadata Load (0.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2441
- ↳ bin/rails:14
2442
-  (0.2ms) BEGIN
2443
- ↳ bin/rails:14
2444
- ActiveRecord::InternalMetadata Create (0.4ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:29:59.559467"], ["updated_at", "2018-07-26 00:29:59.559467"]]
2445
- ↳ bin/rails:14
2446
-  (0.8ms) COMMIT
2447
- ↳ bin/rails:14
2448
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2449
- ↳ bin/rails:14
2450
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2451
- ↳ bin/rails:14
2452
-  (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2453
- ↳ bin/rails:14
2454
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2455
- ↳ bin/rails:14
2456
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2457
- ↳ bin/rails:14
2458
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2459
- ↳ bin/rails:14
2460
-  (108.5ms) DROP DATABASE IF EXISTS "better_record_test"
2461
- ↳ bin/rails:14
2462
-  (256.7ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2463
- ↳ bin/rails:14
2464
- ActiveRecord::InternalMetadata Load (0.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2465
- ↳ bin/rails:14
2466
-  (0.6ms) BEGIN
2467
- ↳ bin/rails:14
2468
- ActiveRecord::InternalMetadata Create (0.4ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:30:29.053185"], ["updated_at", "2018-07-26 00:30:29.053185"]]
2469
- ↳ bin/rails:14
2470
-  (1.0ms) COMMIT
2471
- ↳ bin/rails:14
2472
-  (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2473
- ↳ bin/rails:14
2474
-  (0.2ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2475
- ↳ bin/rails:14
2476
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2477
- ↳ bin/rails:14
2478
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2479
- ↳ bin/rails:14
2480
-  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
2481
- ↳ bin/rails:14
2482
-  (0.1ms) SELECT "ar_internal_metadata"."value" FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 [["key", "environment"]]
2483
- ↳ bin/rails:14
2484
-  (108.5ms) DROP DATABASE IF EXISTS "better_record_test"
2485
- ↳ bin/rails:14
2486
-  (253.1ms) CREATE DATABASE "better_record_test" ENCODING = 'utf8'
2487
- ↳ bin/rails:14
2488
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
2489
- ↳ bin/rails:14
2490
-  (0.1ms) BEGIN
2491
- ↳ bin/rails:14
2492
- ActiveRecord::InternalMetadata Create (0.2ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "test"], ["created_at", "2018-07-26 00:30:50.556432"], ["updated_at", "2018-07-26 00:30:50.556432"]]
2493
- ↳ bin/rails:14
2494
-  (0.7ms) COMMIT
2495
- ↳ bin/rails:14