rails-pg-extras 3.3.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +52 -42
  3. data/app/controllers/rails_pg_extras/web/actions_controller.rb +26 -0
  4. data/app/controllers/rails_pg_extras/web/application_controller.rb +20 -0
  5. data/app/controllers/rails_pg_extras/web/queries_controller.rb +44 -0
  6. data/app/views/layouts/rails_pg_extras/web/application.html.erb +26 -0
  7. data/app/views/rails_pg_extras/web/queries/_diagnose.html.erb +9 -0
  8. data/app/views/rails_pg_extras/web/queries/_result.html.erb +21 -0
  9. data/app/views/rails_pg_extras/web/queries/_unavailable_extensions_warning.html.erb +13 -0
  10. data/app/views/rails_pg_extras/web/queries/index.html.erb +21 -0
  11. data/app/views/rails_pg_extras/web/queries/show.html.erb +24 -0
  12. data/app/views/rails_pg_extras/web/shared/_queries_selector.html.erb +11 -0
  13. data/config/routes.rb +9 -0
  14. data/lib/rails_pg_extras/diagnose_data.rb +12 -0
  15. data/lib/{rails-pg-extras → rails_pg_extras}/diagnose_print.rb +2 -2
  16. data/lib/rails_pg_extras/index_info.rb +11 -0
  17. data/lib/rails_pg_extras/index_info_print.rb +6 -0
  18. data/lib/rails_pg_extras/railtie.rb +7 -0
  19. data/lib/rails_pg_extras/table_info.rb +11 -0
  20. data/lib/rails_pg_extras/table_info_print.rb +6 -0
  21. data/lib/{rails-pg-extras → rails_pg_extras}/tasks/all.rake +7 -7
  22. data/lib/rails_pg_extras/version.rb +5 -0
  23. data/lib/rails_pg_extras/web/engine.rb +7 -0
  24. data/lib/rails_pg_extras/web.rb +6 -0
  25. data/lib/{rails-pg-extras.rb → rails_pg_extras.rb} +24 -23
  26. data/rails-pg-extras.gemspec +4 -4
  27. data/spec/smoke_spec.rb +7 -6
  28. data/spec/spec_helper.rb +4 -4
  29. metadata +28 -15
  30. data/lib/rails-pg-extras/diagnose_data.rb +0 -12
  31. data/lib/rails-pg-extras/index_info.rb +0 -11
  32. data/lib/rails-pg-extras/index_info_print.rb +0 -6
  33. data/lib/rails-pg-extras/railtie.rb +0 -7
  34. data/lib/rails-pg-extras/table_info.rb +0 -11
  35. data/lib/rails-pg-extras/table_info_print.rb +0 -6
  36. data/lib/rails-pg-extras/version.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61f4e9aafcd3569e22233099b2d2935c4d8ca9aebcfb17fef2f8cabfade79155
4
- data.tar.gz: 33728bde4e8af5e78a0f144b25e84a84f2f7ab8d0ebb87872c59628aaee3812d
3
+ metadata.gz: a182232adb71ba714ab127505aa21e410291536a6f6992fed863e6beba4d11d6
4
+ data.tar.gz: c219ee40b92eed9f873dc7a6fbe8e0cd80dd13e70cdd7048827b639d9dbd2f6f
5
5
  SHA512:
6
- metadata.gz: bb505ba7f877771aa4588402c6bb659aed3ab20674217208cba61e70a4181f9eac16fff99c9e28fab58441d828cec23fca40814aec45fedcf780b03b2e93e258
7
- data.tar.gz: caac36a574f9e22d5e5b9a73a6fd11bac2fe3f66a37d63def69dc5c0c77d121010d32c15ad62eed8159a2a55b00b1fef8b2d7689dc6847932312b122018a6e90
6
+ metadata.gz: 82e1cd92bf47fb1588d49bb59fbf10ad5cd24c5878b5fec4025db301707936e6196f8af2ed27d384a5259349be5a6dbfdfc678b1e08ad029a37cc0de178d96ba
7
+ data.tar.gz: 2d7189e0a3953323e5872ad817f015d3f023c90832fe9cf76d42485956f2868089bc9ae00532c377d54dc7f1f764832093cf19778d0f3be02f053eb9d19b9ad1
data/README.md CHANGED
@@ -8,7 +8,7 @@ You can read this blog post for detailed step by step tutorial on how to [optimi
8
8
 
9
9
  **Shameless plug:** rails-pg-extras is one of the tools that I use when conducting Rails performance audits. [Check out my offer](https://pawelurbanek.com/#rails-performance-tuning) if you need help with fine-tuning your app.
10
10
 
11
- Use [rails-pg-extras-web](https://github.com/defkode/rails-pg-extras-web) if you want to see SQL metrics in the UI instead of a command line interface.
11
+ Optionally you can enable a visual interface:
12
12
 
13
13
  ![Web interface](https://github.com/pawurb/rails-pg-extras/raw/master/rails-pg-extras-web.png)
14
14
 
@@ -29,7 +29,7 @@ Alternative versions:
29
29
  In your Gemfile
30
30
 
31
31
  ```ruby
32
- gem "rails-pg-extras"
32
+ gem "rails-pg-extras", require: "rails_pg_extras"
33
33
  ```
34
34
 
35
35
  `calls` and `outliers` queries require [pg_stat_statements](https://www.postgresql.org/docs/current/pgstatstatements.html) extension.
@@ -37,7 +37,7 @@ gem "rails-pg-extras"
37
37
  You can check if it is enabled in your database by running:
38
38
 
39
39
  ```ruby
40
- RailsPGExtras.extensions
40
+ RailsPgExtras.extensions
41
41
  ```
42
42
  You should see the similar line in the output:
43
43
 
@@ -48,7 +48,7 @@ You should see the similar line in the output:
48
48
  `ssl_used` requires `sslinfo` extension, and `buffercache_usage`/`buffercache_usage` queries need `pg_buffercache`. You can enable them all by running:
49
49
 
50
50
  ```ruby
51
- RailsPGExtras.add_extensions
51
+ RailsPgExtras.add_extensions
52
52
  ```
53
53
 
54
54
  ## Usage
@@ -60,7 +60,7 @@ rake pg_extras:cache_hit
60
60
  ```
61
61
 
62
62
  ```ruby
63
- RailsPGExtras.cache_hit
63
+ RailsPgExtras.cache_hit
64
64
  ```
65
65
  ```bash
66
66
  +----------------+------------------------+
@@ -77,15 +77,15 @@ RailsPGExtras.cache_hit
77
77
  By default the ASCII table is displayed, to change to format you need to specify the `in_format` parameter (`[:display_table, :hash, :array, :raw]` options are available):
78
78
 
79
79
  ```ruby
80
- RailsPGExtras.cache_hit(in_format: :hash) =>
80
+ RailsPgExtras.cache_hit(in_format: :hash) =>
81
81
 
82
82
  [{"name"=>"index hit rate", "ratio"=>"0.97796610169491525424"}, {"name"=>"table hit rate", "ratio"=>"0.96724294813466787989"}]
83
83
 
84
- RailsPGExtras.cache_hit(in_format: :array) =>
84
+ RailsPgExtras.cache_hit(in_format: :array) =>
85
85
 
86
86
  [["index hit rate", "0.97796610169491525424"], ["table hit rate", "0.96724294813466787989"]]
87
87
 
88
- RailsPGExtras.cache_hit(in_format: :raw) =>
88
+ RailsPgExtras.cache_hit(in_format: :raw) =>
89
89
 
90
90
  #<PG::Result:0x00007f75777f7328 status=PGRES_TUPLES_OK ntuples=2 nfields=2 cmd_tuples=2>
91
91
  ```
@@ -93,7 +93,7 @@ RailsPGExtras.cache_hit(in_format: :raw) =>
93
93
  Some methods accept an optional `args` param allowing you to customize queries:
94
94
 
95
95
  ```ruby
96
- RailsPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
96
+ RailsPgExtras.long_running_queries(args: { threshold: "200 milliseconds" })
97
97
 
98
98
  ```
99
99
 
@@ -102,7 +102,7 @@ RailsPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
102
102
  The simplest way to start using pg-extras is to execute a `diagnose` method. It runs a set of checks and prints out a report highlighting areas that may require additional investigation:
103
103
 
104
104
  ```ruby
105
- RailsPGExtras.diagnose
105
+ RailsPgExtras.diagnose
106
106
 
107
107
  $ rake pg_extras:diagnose
108
108
  ```
@@ -111,6 +111,16 @@ $ rake pg_extras:diagnose
111
111
 
112
112
  Keep reading to learn about methods that `diagnose` uses under the hood.
113
113
 
114
+ ## Visual interface
115
+
116
+ You can enable UI using a Rails engine by adding the following code in `config/routes.rb`:
117
+
118
+ ```ruby
119
+ mount RailsPgExtras::Web::Engine, at: 'pg_extras'
120
+ ```
121
+
122
+ On production environment you can enable HTTP basic auth by specifying `RAILS_PG_EXTRAS_USER` and `RAILS_PG_EXTRAS_PASSWORD` variables.
123
+
114
124
  ## Available methods
115
125
 
116
126
  ### `table_info`
@@ -118,7 +128,7 @@ Keep reading to learn about methods that `diagnose` uses under the hood.
118
128
  This method displays metadata metrics for all or a selected table. You can use it to check the table's size, its cache hit metrics, and whether it is correctly indexed. Many sequential scans or no index scans are potential indicators of misconfigured indexes. This method aggregates data provided by other methods in an easy to analyze summary format.
119
129
 
120
130
  ```ruby
121
- RailsPGExtras.table_info(args: { table_name: "users" })
131
+ RailsPgExtras.table_info(args: { table_name: "users" })
122
132
 
123
133
  | Table name | Table size | Table cache hit | Indexes cache hit | Estimated rows | Sequential scans | Indexes scans |
124
134
  +------------+------------+-------------------+--------------------+----------------+------------------+---------------+
@@ -132,7 +142,7 @@ This method returns summary info about database indexes. You can check index siz
132
142
 
133
143
  ```ruby
134
144
 
135
- RailsPGExtras.index_info(args: { table_name: "users" })
145
+ RailsPgExtras.index_info(args: { table_name: "users" })
136
146
 
137
147
  | Index name | Table name | Columns | Index size | Index scans | Null frac |
138
148
  +-------------------------------+------------+----------------+------------+-------------+-----------+
@@ -148,7 +158,7 @@ RailsPGExtras.index_info(args: { table_name: "users" })
148
158
  ### `cache_hit`
149
159
 
150
160
  ```ruby
151
- RailsPGExtras.cache_hit
161
+ RailsPgExtras.cache_hit
152
162
 
153
163
  $ rake pg_extras:cache_hit
154
164
 
@@ -167,7 +177,7 @@ This command provides information on the efficiency of the buffer cache, for bot
167
177
 
168
178
  ```ruby
169
179
 
170
- RailsPGExtras.index_cache_hit
180
+ RailsPgExtras.index_cache_hit
171
181
 
172
182
  $ rake pg_extras:index_cache_hit
173
183
 
@@ -187,7 +197,7 @@ The same as `cache_hit` with each table's indexes cache hit info displayed separ
187
197
 
188
198
  ```ruby
189
199
 
190
- RailsPGExtras.table_cache_hit
200
+ RailsPgExtras.table_cache_hit
191
201
 
192
202
  $ rake pg_extras:table_cache_hit
193
203
 
@@ -207,7 +217,7 @@ The same as `cache_hit` with each table's cache hit info displayed seperately.
207
217
 
208
218
  ```ruby
209
219
 
210
- RailsPGExtras.db_settings
220
+ RailsPgExtras.db_settings
211
221
 
212
222
  $ rake pg_extras:db_settings
213
223
 
@@ -229,7 +239,7 @@ This method displays values for selected PostgreSQL settings. You can compare th
229
239
 
230
240
  ```ruby
231
241
 
232
- RailsPGExtras.ssl_used
242
+ RailsPgExtras.ssl_used
233
243
 
234
244
  | ssl_is_used |
235
245
  +---------------------------------+
@@ -242,7 +252,7 @@ Returns boolean indicating if an encrypted SSL is currently used. Connecting to
242
252
  ### `index_usage`
243
253
 
244
254
  ```ruby
245
- RailsPGExtras.index_usage
255
+ RailsPgExtras.index_usage
246
256
 
247
257
  $ rake pg_extras:index_usage
248
258
 
@@ -261,7 +271,7 @@ This command provides information on the efficiency of indexes, represented as w
261
271
  ### `locks`
262
272
 
263
273
  ```ruby
264
- RailsPGExtras.locks
274
+ RailsPgExtras.locks
265
275
 
266
276
  $ rake pg_extras:locks
267
277
 
@@ -283,7 +293,7 @@ This command displays queries that have taken out an exclusive lock on a relatio
283
293
  ### `all_locks`
284
294
 
285
295
  ```ruby
286
- RailsPGExtras.all_locks
296
+ RailsPgExtras.all_locks
287
297
 
288
298
  $ rake pg_extras:all_locks
289
299
  ```
@@ -293,7 +303,7 @@ This command displays all the current locks, regardless of their type.
293
303
  ### `outliers`
294
304
 
295
305
  ```ruby
296
- RailsPGExtras.outliers(args: { limit: 20 })
306
+ RailsPgExtras.outliers(args: { limit: 20 })
297
307
 
298
308
  $ rake pg_extras:outliers
299
309
 
@@ -317,7 +327,7 @@ Typically, an efficient query will have an appropriate ratio of calls to total e
317
327
  ### `calls`
318
328
 
319
329
  ```ruby
320
- RailsPGExtras.calls(args: { limit: 10 })
330
+ RailsPgExtras.calls(args: { limit: 10 })
321
331
 
322
332
  $ rake pg_extras:calls
323
333
 
@@ -338,7 +348,7 @@ This command is much like `pg:outliers`, but ordered by the number of times a st
338
348
  ### `blocking`
339
349
 
340
350
  ```ruby
341
- RailsPGExtras.blocking
351
+ RailsPgExtras.blocking
342
352
 
343
353
  $ rake pg_extras:blocking
344
354
 
@@ -355,7 +365,7 @@ This command displays statements that are currently holding locks that other sta
355
365
  ### `total_index_size`
356
366
 
357
367
  ```ruby
358
- RailsPGExtras.total_index_size
368
+ RailsPgExtras.total_index_size
359
369
 
360
370
  $ rake pg_extras:total_index_size
361
371
 
@@ -370,7 +380,7 @@ This command displays the total size of all indexes on the database, in MB. It i
370
380
  ### `index_size`
371
381
 
372
382
  ```ruby
373
- RailsPGExtras.index_size
383
+ RailsPgExtras.index_size
374
384
 
375
385
  $ rake pg_extras:index_size
376
386
  name | size
@@ -393,7 +403,7 @@ This command displays the size of each each index in the database, in MB. It is
393
403
  ### `table_size`
394
404
 
395
405
  ```ruby
396
- RailsPGExtras.table_size
406
+ RailsPgExtras.table_size
397
407
 
398
408
  $ rake pg_extras:table_size
399
409
 
@@ -412,7 +422,7 @@ This command displays the size of each table and materialized view in the databa
412
422
  ### `table_indexes_size`
413
423
 
414
424
  ```ruby
415
- RailsPGExtras.table_indexes_size
425
+ RailsPgExtras.table_indexes_size
416
426
 
417
427
  $ rake pg_extras:table_indexes_size
418
428
 
@@ -431,7 +441,7 @@ This command displays the total size of indexes for each table and materialized
431
441
  ### `total_table_size`
432
442
 
433
443
  ```ruby
434
- RailsPGExtras.total_table_size
444
+ RailsPgExtras.total_table_size
435
445
 
436
446
  $ rake pg_extras:total_table_size
437
447
 
@@ -450,7 +460,7 @@ This command displays the total size of each table and materialized view in the
450
460
  ### `unused_indexes`
451
461
 
452
462
  ```ruby
453
- RailsPGExtras.unused_indexes(args: { max_scans: 20 })
463
+ RailsPgExtras.unused_indexes(args: { max_scans: 20 })
454
464
 
455
465
  $ rake pg_extras:unused_indexes
456
466
 
@@ -470,7 +480,7 @@ This command displays indexes that have < 50 scans recorded against them, and ar
470
480
 
471
481
  ```ruby
472
482
 
473
- RailsPGExtras.duplicate_indexes
483
+ RailsPgExtras.duplicate_indexes
474
484
 
475
485
  | size | idx1 | idx2 | idx3 | idx4 |
476
486
  +------------+--------------+----------------+----------+-----------+
@@ -483,7 +493,7 @@ This command displays multiple indexes that have the same set of columns, same o
483
493
 
484
494
  ```ruby
485
495
 
486
- RailsPGExtras.null_indexes(args: { min_relation_size_mb: 10 })
496
+ RailsPgExtras.null_indexes(args: { min_relation_size_mb: 10 })
487
497
 
488
498
  $ rake pg_extras:null_indexes
489
499
 
@@ -502,7 +512,7 @@ This command displays indexes that contain `NULL` values. A high ratio of `NULL`
502
512
  ### `seq_scans`
503
513
 
504
514
  ```ruby
505
- RailsPGExtras.seq_scans
515
+ RailsPgExtras.seq_scans
506
516
 
507
517
  $ rake pg_extras:seq_scans
508
518
 
@@ -526,7 +536,7 @@ This command displays the number of sequential scans recorded against all tables
526
536
  ### `long_running_queries`
527
537
 
528
538
  ```ruby
529
- RailsPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
539
+ RailsPgExtras.long_running_queries(args: { threshold: "200 milliseconds" })
530
540
 
531
541
  $ rake pg_extras:long_running_queries
532
542
 
@@ -543,7 +553,7 @@ This command displays currently running queries, that have been running for long
543
553
  ### `records_rank`
544
554
 
545
555
  ```ruby
546
- RailsPGExtras.records_rank
556
+ RailsPgExtras.records_rank
547
557
 
548
558
  $ rake pg_extras:records_rank
549
559
 
@@ -563,7 +573,7 @@ This command displays an estimated count of rows per table, descending by estima
563
573
  ### `bloat`
564
574
 
565
575
  ```ruby
566
- RailsPGExtras.bloat
576
+ RailsPgExtras.bloat
567
577
 
568
578
  $ rake pg_extras:bloat
569
579
 
@@ -584,7 +594,7 @@ This command displays an estimation of table "bloat" – space allocated to a re
584
594
  ### `vacuum_stats`
585
595
 
586
596
  ```ruby
587
- RailsPGExtras.vacuum_stats
597
+ RailsPgExtras.vacuum_stats
588
598
 
589
599
  $ rake pg_extras:vacuum_stats
590
600
 
@@ -603,7 +613,7 @@ This command displays statistics related to vacuum operations for each table, in
603
613
 
604
614
  ```ruby
605
615
 
606
- RailsPGExtras.kill_all
616
+ RailsPgExtras.kill_all
607
617
 
608
618
  ```
609
619
 
@@ -612,7 +622,7 @@ This commands kills all the currently active connections to the database. It can
612
622
  ### `pg_stat_statements_reset`
613
623
 
614
624
  ```ruby
615
- RailsPGExtras.pg_stat_statements_reset
625
+ RailsPgExtras.pg_stat_statements_reset
616
626
  ```
617
627
 
618
628
  This command discards all statistics gathered so far by pg_stat_statements.
@@ -620,7 +630,7 @@ This command discards all statistics gathered so far by pg_stat_statements.
620
630
  ### `buffercache_stats`
621
631
 
622
632
  ```ruby
623
- RailsPGExtras.buffercache_stats(args: { limit: 10 })
633
+ RailsPgExtras.buffercache_stats(args: { limit: 10 })
624
634
  ```
625
635
 
626
636
  This command shows the relations buffered in database share buffer, ordered by percentage taken. It also shows that how much of the whole relation is buffered.
@@ -628,7 +638,7 @@ This command shows the relations buffered in database share buffer, ordered by p
628
638
  ### `buffercache_usage`
629
639
 
630
640
  ```ruby
631
- RailsPGExtras.buffercache_usage(args: { limit: 20 })
641
+ RailsPgExtras.buffercache_usage(args: { limit: 20 })
632
642
  ```
633
643
 
634
644
  This command calculates how many blocks from which table are currently cached.
@@ -637,7 +647,7 @@ This command calculates how many blocks from which table are currently cached.
637
647
 
638
648
  ```ruby
639
649
 
640
- RailsPGExtras.extensions
650
+ RailsPgExtras.extensions
641
651
 
642
652
  $ rake pg_extras:extensions
643
653
 
@@ -651,7 +661,7 @@ This command lists all the currently installed and available PostgreSQL extensio
651
661
  ### mandelbrot
652
662
 
653
663
  ```ruby
654
- RailsPGExtras.mandelbrot
664
+ RailsPgExtras.mandelbrot
655
665
 
656
666
  $ rake pg_extras:mandelbrot
657
667
  ```
@@ -0,0 +1,26 @@
1
+ module RailsPgExtras::Web
2
+ class ActionsController < ApplicationController
3
+ def kill_all
4
+ run(:kill_all)
5
+ end
6
+
7
+ def pg_stat_statements_reset
8
+ run(:pg_stat_statements_reset)
9
+ end
10
+
11
+ def add_extensions
12
+ run(:add_extensions)
13
+ end
14
+
15
+ private
16
+
17
+ def run(action)
18
+ begin
19
+ RailsPgExtras.run_query(query_name: action, in_format: :raw)
20
+ redirect_to root_path, notice: "Successfully ran #{action}"
21
+ rescue ActiveRecord::StatementInvalid => e
22
+ redirect_to root_path, alert: "Error: #{e.message}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ require "rails_pg_extras"
2
+ require "rails_pg_extras/version"
3
+
4
+ module RailsPgExtras::Web
5
+ class ApplicationController < ActionController::Base
6
+ layout "rails_pg_extras/web/application"
7
+
8
+ REQUIRED_EXTENSIONS = {
9
+ pg_stat_statements: %i[calls outliers pg_stat_statements_reset],
10
+ pg_buffercache: %i[buffercache_stats buffercache_usage],
11
+ sslinfo: %i[ssl_used]
12
+ }
13
+
14
+ ACTIONS = %i[kill_all pg_stat_statements_reset add_extensions]
15
+
16
+ if Rails.env.production? && ENV['RAILS_PG_EXTRAS_USER'].present? && ENV['RAILS_PG_EXTRAS_PASSWORD'].present?
17
+ http_basic_authenticate_with name: ENV['RAILS_PG_EXTRAS_USER'], password: ENV['RAILS_PG_EXTRAS_PASSWORD']
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,44 @@
1
+ module RailsPgExtras::Web
2
+ class QueriesController < ApplicationController
3
+ before_action :load_queries
4
+ helper_method :unavailable_extensions
5
+
6
+ def index
7
+ if params[:query_name].present?
8
+ @query_name = params[:query_name].to_sym.presence_in(@all_queries.keys)
9
+ return unless @query_name
10
+
11
+ begin
12
+ @result = RailsPgExtras.run_query(query_name: @query_name.to_sym, in_format: :raw)
13
+ rescue ActiveRecord::StatementInvalid => e
14
+ @error = e.message
15
+ end
16
+
17
+ render :show
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def load_queries
24
+ @all_queries = (RailsPgExtras::QUERIES - ACTIONS).inject({}) do |memo, query_name|
25
+ unless query_name.in? %i[mandelbrot]
26
+ memo[query_name] = { disabled: query_disabled?(query_name) }
27
+ end
28
+
29
+ memo
30
+ end
31
+ end
32
+
33
+ def query_disabled?(query_name)
34
+ unavailable_extensions.values.flatten.include?(query_name)
35
+ end
36
+
37
+ def unavailable_extensions
38
+ return @unavailable_extensions if defined?(@unavailable_extensions)
39
+
40
+ enabled_extensions = ActiveRecord::Base.connection.extensions
41
+ @unavailable_extensions = REQUIRED_EXTENSIONS.delete_if { |ext| ext.to_s.in?(enabled_extensions) }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= content_for :title %> | v<%= RailsPgExtras::VERSION %></title>
5
+ <%= javascript_include_tag "https://unpkg.com/@rails/ujs" %>
6
+ <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body class="p-5 text-xs">
10
+ <% if flash[:notice] %>
11
+ <div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-4" role="alert">
12
+ <p class="font-bold">Notice</p>
13
+ <p><%= flash[:notice] %></p>
14
+ </div>
15
+ <% end %>
16
+
17
+ <% if flash[:alert] %>
18
+ <div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4" role="alert">
19
+ <p class="font-bold">Alert</p>
20
+ <p><%= flash[:alert] %></p>
21
+ </div>
22
+ <% end %>
23
+
24
+ <%= yield %>
25
+ </body>
26
+ </html>
@@ -0,0 +1,9 @@
1
+ <h1 class="font-bold text-xl my-5">Diagnose</h1>
2
+ <table class="w-full font-mono border-collapse border my-5">
3
+ <% RailsPgExtras.diagnose(in_format: :hash).each do |diagnosis| %>
4
+ <tr class="<%= diagnosis[:ok] ? 'bg-green-300' : 'bg-red-300' %>">
5
+ <td class='p-1 border font-bold'><%= diagnosis[:check_name] %></td>
6
+ <td class='p-1 border'><%= diagnosis[:message] %></td>
7
+ </tr>
8
+ <% end %>
9
+ </table>
@@ -0,0 +1,21 @@
1
+ <h1 class="font-bold text-xl my-5"><%= title %></h1>
2
+
3
+ <table class="w-full font-mono border-collapse border my-5">
4
+ <thead>
5
+ <tr class="bg-gray-300">
6
+ <% headers.each do |header| %>
7
+ <th class="p-2 border text-left"><%= header %></th>
8
+ <% end %>
9
+ </tr>
10
+ </thead>
11
+ <tbody>
12
+ <% rows.each.with_index do |row, i| %>
13
+ <tr class="hover:bg-gray-400 hover:text-white <%= i.even? ? "bg-gray-100" : "bg-gray-200" %>">
14
+ <% row.each do |column| %>
15
+ <td class="p-1 border"><%= column %></td>
16
+ <% end %>
17
+ </tr>
18
+ <% end %>
19
+ </tbody>
20
+ </table>
21
+ <span class="italic">run_at: <%= Time.now.utc %></span>
@@ -0,0 +1,13 @@
1
+ <div class="text-red-500 p-3 font-mono my-5">
2
+ <% unavailable_extensions.each do |extension, queries| %>
3
+ WARNING: Queries <%= queries.map { |q| "<b><u>#{q}</u></b>" }.join(", ").html_safe %> require extension: <b><%= extension %></b>
4
+ <br>
5
+ <% end %>
6
+ </div>
7
+
8
+ <%= link_to "Enable extensions", add_extensions_action_path,
9
+ method: "post",
10
+ data: {
11
+ confirm: "This command will enable following extensions: #{unavailable_extensions.keys.join(', ')}. Do you want to proceeed?"
12
+ }, class: 'border p-3 bg-green-500 text-white hover:bg-green-600 font-bold rounded' %>
13
+
@@ -0,0 +1,21 @@
1
+ <%= content_for :title, "pg_extras" %>
2
+ <%= render "rails_pg_extras/web/shared/queries_selector" %>
3
+ <%= render "unavailable_extensions_warning" if unavailable_extensions.any? %>
4
+ <%= render "diagnose" %>
5
+
6
+ <h1 class="font-bold text-xl my-5">Actions</h1>
7
+
8
+ <%= link_to "kill_all", kill_all_action_path,
9
+ method: "post",
10
+ data: {
11
+ confirm: "This commands kills all the currently active connections to the database. Do you want to proceed?"
12
+ },
13
+ class: 'border p-3 bg-red-500 text-white hover:bg-red-600 font-bold rounded'
14
+ %>
15
+
16
+ <%= link_to "pg_stat_statements_reset", pg_stat_statements_reset_action_path,
17
+ method: "post",
18
+ data: {
19
+ confirm: "This command discards all statistics gathered so far by pg_stat_statements. Do you want to proceed?"
20
+ }, class: 'border p-3 bg-blue-500 text-white hover:bg-blue-600 font-bold rounded'
21
+ %>
@@ -0,0 +1,24 @@
1
+ <%= content_for :title, params[:query_name].presence || "pg_extras" %>
2
+ <%= render "rails_pg_extras/web/shared/queries_selector" %>
3
+
4
+ <% if @error %>
5
+ <div class="text-red-500 p-3 font-mono my-5"><%= @error %></div>
6
+ <% else %>
7
+ <% if @result&.any? %>
8
+ <%= render "result",
9
+ title: RubyPgExtras.description_for(query_name: @query_name),
10
+ headers: @result[0].keys,
11
+ rows: @result.values
12
+ %>
13
+ <% else %>
14
+ <div class="font-mono p-3 bg-gray-100 mt-3">No results</div>
15
+ <% end %>
16
+ <% end %>
17
+
18
+ <style>
19
+ @media print {
20
+ form {
21
+ display: none
22
+ }
23
+ }
24
+ </style>
@@ -0,0 +1,11 @@
1
+ <%= form_with url: queries_path, id: "queries", method: :get do |f| %>
2
+ <%= f.select :query_name, options_for_select(@all_queries, params[:query_name]),
3
+ {prompt: "--- select query ---"},
4
+ {class: "border p-2 font-bold", autofocus: true}
5
+ %>
6
+ <% end %>
7
+ <script>
8
+ document.getElementById('queries').addEventListener('change', (e) => {
9
+ e.target.form.submit()
10
+ })
11
+ </script>
data/config/routes.rb ADDED
@@ -0,0 +1,9 @@
1
+ RailsPgExtras::Web::Engine.routes.draw do
2
+ resources :queries, only: [:index]
3
+
4
+ post "/actions/kill_all" => "actions#kill_all", as: :kill_all_action
5
+ post "/actions/pg_stat_statements_reset" => "actions#pg_stat_statements_reset", as: :pg_stat_statements_reset_action
6
+ post "/actions/add_extensions" => "actions#add_extensions", as: :add_extensions_action
7
+
8
+ root to: "queries#index"
9
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsPgExtras
4
+ class DiagnoseData < ::RubyPgExtras::DiagnoseData
5
+
6
+ private
7
+
8
+ def query_module
9
+ RailsPgExtras
10
+ end
11
+ end
12
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RailsPGExtras
4
- class DiagnosePrint < RubyPGExtras::DiagnosePrint
3
+ module RailsPgExtras
4
+ class DiagnosePrint < ::RubyPgExtras::DiagnosePrint
5
5
 
6
6
  private
7
7
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsPgExtras
4
+ class IndexInfo < RubyPgExtras::IndexInfo
5
+ private
6
+
7
+ def query_module
8
+ RailsPgExtras
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsPgExtras
4
+ class IndexInfoPrint < RubyPgExtras::IndexInfoPrint
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RailsPgExtras::Railtie < Rails::Railtie
4
+ rake_tasks do
5
+ load 'rails_pg_extras/tasks/all.rake'
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsPgExtras
4
+ class TableInfo < RubyPgExtras::TableInfo
5
+ private
6
+
7
+ def query_module
8
+ RailsPgExtras
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsPgExtras
4
+ class TableInfoPrint < RubyPgExtras::TableInfoPrint
5
+ end
6
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rails-pg-extras'
3
+ require 'rails_pg_extras'
4
4
 
5
5
  namespace :pg_extras do
6
6
  task :establish_connection do
@@ -13,25 +13,25 @@ namespace :pg_extras do
13
13
  end
14
14
  end
15
15
 
16
- RailsPGExtras::QUERIES.each do |query_name|
17
- desc RubyPGExtras.description_for(query_name: query_name)
16
+ RailsPgExtras::QUERIES.each do |query_name|
17
+ desc RubyPgExtras.description_for(query_name: query_name)
18
18
  task query_name.to_sym => :establish_connection do
19
- RailsPGExtras.public_send(query_name)
19
+ RailsPgExtras.public_send(query_name)
20
20
  end
21
21
  end
22
22
 
23
23
  desc "Generate a PostgreSQL healthcheck report"
24
24
  task diagnose: :establish_connection do
25
- RailsPGExtras.diagnose
25
+ RailsPgExtras.diagnose
26
26
  end
27
27
 
28
28
  desc "Display tables metadata metrics"
29
29
  task table_info: :establish_connection do
30
- RailsPGExtras.table_info
30
+ RailsPgExtras.table_info
31
31
  end
32
32
 
33
33
  desc "Display indexes metadata metrics"
34
34
  task index_info: :establish_connection do
35
- RailsPGExtras.index_info
35
+ RailsPgExtras.index_info
36
36
  end
37
37
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsPgExtras
4
+ VERSION = "4.0.0"
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'rails'
2
+
3
+ module RailsPgExtras::Web
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace RailsPgExtras::Web
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ require "rails_pg_extras/web/engine"
2
+
3
+ module RailsPgExtras
4
+ module Web
5
+ end
6
+ end
@@ -1,18 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'terminal-table'
4
- require 'ruby-pg-extras'
5
- require 'rails-pg-extras/diagnose_data'
6
- require 'rails-pg-extras/diagnose_print'
7
- require 'rails-pg-extras/index_info'
8
- require 'rails-pg-extras/index_info_print'
9
- require 'rails-pg-extras/table_info'
10
- require 'rails-pg-extras/table_info_print'
4
+ require 'ruby_pg_extras'
5
+ require 'rails_pg_extras/diagnose_data'
6
+ require 'rails_pg_extras/diagnose_print'
7
+ require 'rails_pg_extras/index_info'
8
+ require 'rails_pg_extras/index_info_print'
9
+ require 'rails_pg_extras/table_info'
10
+ require 'rails_pg_extras/table_info_print'
11
+ require 'rails_pg_extras/web'
11
12
 
12
- module RailsPGExtras
13
- QUERIES = RubyPGExtras::QUERIES
14
- DEFAULT_ARGS = RubyPGExtras::DEFAULT_ARGS
15
- NEW_PG_STAT_STATEMENTS = RubyPGExtras::NEW_PG_STAT_STATEMENTS
13
+ module RailsPgExtras
14
+ QUERIES = RubyPgExtras::QUERIES
15
+ DEFAULT_ARGS = RubyPgExtras::DEFAULT_ARGS
16
+ NEW_PG_STAT_STATEMENTS = RubyPgExtras::NEW_PG_STAT_STATEMENTS
16
17
 
17
18
  QUERIES.each do |query_name|
18
19
  define_singleton_method query_name do |options = {}|
@@ -26,7 +27,7 @@ module RailsPGExtras
26
27
 
27
28
  def self.run_query(query_name:, in_format:, args: {})
28
29
  if %i(calls outliers).include?(query_name)
29
- pg_stat_statements_ver = RailsPGExtras.connection.execute("select installed_version from pg_available_extensions where name='pg_stat_statements'")
30
+ pg_stat_statements_ver = RailsPgExtras.connection.execute("select installed_version from pg_available_extensions where name='pg_stat_statements'")
30
31
  .to_a[0].fetch("installed_version", nil)
31
32
  if pg_stat_statements_ver != nil
32
33
  if Gem::Version.new(pg_stat_statements_ver) < Gem::Version.new(NEW_PG_STAT_STATEMENTS)
@@ -36,25 +37,25 @@ module RailsPGExtras
36
37
  end
37
38
 
38
39
  sql = if (custom_args = DEFAULT_ARGS[query_name].merge(args)) != {}
39
- RubyPGExtras.sql_for(query_name: query_name) % custom_args
40
+ RubyPgExtras.sql_for(query_name: query_name) % custom_args
40
41
  else
41
- RubyPGExtras.sql_for(query_name: query_name)
42
+ RubyPgExtras.sql_for(query_name: query_name)
42
43
  end
43
44
 
44
45
  result = connection.execute(sql)
45
46
 
46
- RubyPGExtras.display_result(
47
+ RubyPgExtras.display_result(
47
48
  result,
48
- title: RubyPGExtras.description_for(query_name: query_name),
49
+ title: RubyPgExtras.description_for(query_name: query_name),
49
50
  in_format: in_format
50
51
  )
51
52
  end
52
53
 
53
54
  def self.diagnose(in_format: :display_table)
54
- data = RailsPGExtras::DiagnoseData.call
55
+ data = RailsPgExtras::DiagnoseData.call
55
56
 
56
57
  if in_format == :display_table
57
- RailsPGExtras::DiagnosePrint.call(data)
58
+ RailsPgExtras::DiagnosePrint.call(data)
58
59
  elsif in_format == :hash
59
60
  data
60
61
  else
@@ -63,10 +64,10 @@ module RailsPGExtras
63
64
  end
64
65
 
65
66
  def self.index_info(args: {}, in_format: :display_table)
66
- data = RailsPGExtras::IndexInfo.call(args[:table_name])
67
+ data = RailsPgExtras::IndexInfo.call(args[:table_name])
67
68
 
68
69
  if in_format == :display_table
69
- RailsPGExtras::IndexInfoPrint.call(data)
70
+ RailsPgExtras::IndexInfoPrint.call(data)
70
71
  elsif in_format == :hash
71
72
  data
72
73
  elsif in_format == :array
@@ -77,10 +78,10 @@ module RailsPGExtras
77
78
  end
78
79
 
79
80
  def self.table_info(args: {}, in_format: :display_table)
80
- data = RailsPGExtras::TableInfo.call(args[:table_name])
81
+ data = RailsPgExtras::TableInfo.call(args[:table_name])
81
82
 
82
83
  if in_format == :display_table
83
- RailsPGExtras::TableInfoPrint.call(data)
84
+ RailsPgExtras::TableInfoPrint.call(data)
84
85
  elsif in_format == :hash
85
86
  data
86
87
  elsif in_format == :array
@@ -95,4 +96,4 @@ module RailsPGExtras
95
96
  end
96
97
  end
97
98
 
98
- require 'rails-pg-extras/railtie' if defined?(Rails)
99
+ require 'rails_pg_extras/railtie' if defined?(Rails)
@@ -1,11 +1,11 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'rails-pg-extras/version'
4
+ require 'rails_pg_extras/version'
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "rails-pg-extras"
8
- s.version = RailsPGExtras::VERSION
8
+ s.version = RailsPgExtras::VERSION
9
9
  s.authors = ["pawurb"]
10
10
  s.email = ["contact@pawelurbanek.com"]
11
11
  s.summary = %q{ Rails PostgreSQL performance database insights }
@@ -15,8 +15,8 @@ Gem::Specification.new do |s|
15
15
  s.test_files = s.files.grep(%r{^(spec)/})
16
16
  s.require_paths = ["lib"]
17
17
  s.license = "MIT"
18
- s.add_dependency "ruby-pg-extras", RailsPGExtras::VERSION
19
- s.add_dependency "activerecord"
18
+ s.add_dependency "ruby-pg-extras", RailsPgExtras::VERSION
19
+ s.add_dependency "rails"
20
20
  s.add_development_dependency "rake"
21
21
  s.add_development_dependency "rspec"
22
22
 
data/spec/smoke_spec.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
+ require 'rails_pg_extras'
4
5
 
5
- describe RailsPGExtras do
6
- RailsPGExtras::QUERIES.each do |query_name|
6
+ describe RailsPgExtras do
7
+ RailsPgExtras::QUERIES.each do |query_name|
7
8
  it "#{query_name} query can be executed" do
8
9
  expect do
9
- RailsPGExtras.run_query(
10
+ RailsPgExtras.run_query(
10
11
  query_name: query_name,
11
12
  in_format: :hash
12
13
  )
@@ -16,15 +17,15 @@ describe RailsPGExtras do
16
17
 
17
18
  it "runs the custom methods" do
18
19
  expect do
19
- RailsPGExtras.diagnose(in_format: :hash)
20
+ RailsPgExtras.diagnose(in_format: :hash)
20
21
  end.not_to raise_error
21
22
 
22
23
  expect do
23
- RailsPGExtras.index_info(in_format: :hash)
24
+ RailsPgExtras.index_info(in_format: :hash)
24
25
  end.not_to raise_error
25
26
 
26
27
  expect do
27
- RailsPGExtras.table_info(in_format: :hash)
28
+ RailsPgExtras.table_info(in_format: :hash)
28
29
  end.not_to raise_error
29
30
  end
30
31
  end
data/spec/spec_helper.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require 'rubygems'
4
4
  require 'bundler/setup'
5
5
  require 'active_record'
6
- require_relative '../lib/rails-pg-extras'
6
+ require_relative '../lib/rails_pg_extras'
7
7
 
8
8
  pg_version = ENV["PG_VERSION"]
9
9
 
@@ -24,9 +24,9 @@ RSpec.configure do |config|
24
24
  ActiveRecord::Base.establish_connection(
25
25
  ENV.fetch("DATABASE_URL")
26
26
  )
27
- RailsPGExtras.connection.execute("CREATE EXTENSION IF NOT EXISTS pg_stat_statements;")
28
- RailsPGExtras.connection.execute("CREATE EXTENSION IF NOT EXISTS pg_buffercache;")
29
- RailsPGExtras.connection.execute("CREATE EXTENSION IF NOT EXISTS sslinfo;")
27
+ RailsPgExtras.connection.execute("CREATE EXTENSION IF NOT EXISTS pg_stat_statements;")
28
+ RailsPgExtras.connection.execute("CREATE EXTENSION IF NOT EXISTS pg_buffercache;")
29
+ RailsPgExtras.connection.execute("CREATE EXTENSION IF NOT EXISTS sslinfo;")
30
30
  end
31
31
 
32
32
  config.after :suite do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-pg-extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-22 00:00:00.000000000 Z
11
+ date: 2022-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-pg-extras
@@ -16,16 +16,16 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 3.3.0
19
+ version: 4.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 3.3.0
26
+ version: 4.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: activerecord
28
+ name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -81,17 +81,30 @@ files:
81
81
  - LICENSE.txt
82
82
  - README.md
83
83
  - Rakefile
84
+ - app/controllers/rails_pg_extras/web/actions_controller.rb
85
+ - app/controllers/rails_pg_extras/web/application_controller.rb
86
+ - app/controllers/rails_pg_extras/web/queries_controller.rb
87
+ - app/views/layouts/rails_pg_extras/web/application.html.erb
88
+ - app/views/rails_pg_extras/web/queries/_diagnose.html.erb
89
+ - app/views/rails_pg_extras/web/queries/_result.html.erb
90
+ - app/views/rails_pg_extras/web/queries/_unavailable_extensions_warning.html.erb
91
+ - app/views/rails_pg_extras/web/queries/index.html.erb
92
+ - app/views/rails_pg_extras/web/queries/show.html.erb
93
+ - app/views/rails_pg_extras/web/shared/_queries_selector.html.erb
94
+ - config/routes.rb
84
95
  - docker-compose.yml.sample
85
- - lib/rails-pg-extras.rb
86
- - lib/rails-pg-extras/diagnose_data.rb
87
- - lib/rails-pg-extras/diagnose_print.rb
88
- - lib/rails-pg-extras/index_info.rb
89
- - lib/rails-pg-extras/index_info_print.rb
90
- - lib/rails-pg-extras/railtie.rb
91
- - lib/rails-pg-extras/table_info.rb
92
- - lib/rails-pg-extras/table_info_print.rb
93
- - lib/rails-pg-extras/tasks/all.rake
94
- - lib/rails-pg-extras/version.rb
96
+ - lib/rails_pg_extras.rb
97
+ - lib/rails_pg_extras/diagnose_data.rb
98
+ - lib/rails_pg_extras/diagnose_print.rb
99
+ - lib/rails_pg_extras/index_info.rb
100
+ - lib/rails_pg_extras/index_info_print.rb
101
+ - lib/rails_pg_extras/railtie.rb
102
+ - lib/rails_pg_extras/table_info.rb
103
+ - lib/rails_pg_extras/table_info_print.rb
104
+ - lib/rails_pg_extras/tasks/all.rake
105
+ - lib/rails_pg_extras/version.rb
106
+ - lib/rails_pg_extras/web.rb
107
+ - lib/rails_pg_extras/web/engine.rb
95
108
  - rails-pg-extras-diagnose.png
96
109
  - rails-pg-extras-web.png
97
110
  - rails-pg-extras.gemspec
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsPGExtras
4
- class DiagnoseData < RubyPGExtras::DiagnoseData
5
-
6
- private
7
-
8
- def query_module
9
- RailsPGExtras
10
- end
11
- end
12
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsPGExtras
4
- class IndexInfo < RubyPGExtras::IndexInfo
5
- private
6
-
7
- def query_module
8
- RailsPGExtras
9
- end
10
- end
11
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsPGExtras
4
- class IndexInfoPrint < RubyPGExtras::IndexInfoPrint
5
- end
6
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class RailsPGExtras::Railtie < Rails::Railtie
4
- rake_tasks do
5
- load 'rails-pg-extras/tasks/all.rake'
6
- end
7
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsPGExtras
4
- class TableInfo < RubyPGExtras::TableInfo
5
- private
6
-
7
- def query_module
8
- RailsPGExtras
9
- end
10
- end
11
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsPGExtras
4
- class TableInfoPrint < RubyPGExtras::TableInfoPrint
5
- end
6
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsPGExtras
4
- VERSION = "3.3.0"
5
- end