sql_tracker 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d8d236c5adb10928d77ae8547ab0a88fffe16c4c
4
- data.tar.gz: af52c90be114c030abbe35ee5c4babda01b4a21f
3
+ metadata.gz: 65a35dfb502edde6f30c4f342ea42e3d118f7459
4
+ data.tar.gz: bf16c892168e7df593c3812352d53aefea633172
5
5
  SHA512:
6
- metadata.gz: d0231bef73e7f00395eebc0afce207544cade7bd702b57abeea697ffd9dbd9da0b4cb4d42023b85b4a91d2d8c3044a936ffbbee720b59266b0e023cb5c0a08f3
7
- data.tar.gz: b41ac6f658f2dfcd9ebeab95bd694c998e8cf6a4d8ec5753564088af0110b918efa437a66fbd4687df206369d5a53927c266427f6c91ea9fbcdfed29eebd762a
6
+ metadata.gz: deacfae440353615e04f3b88acd48c8e0ea38754f694b2cab0eec0946b878c7e6b338e830d955501e5f905d3fece5a5c726604534d9b7814dca5350dd9e45e9f
7
+ data.tar.gz: d57bc72264b859df7d681f371507c82c19e121f71ba49fb6df5dac99ad27535adbf4f0fe2b37d8cea64475c57613ffd042bad8c367aca658cf778b77ef6a78e2
data/README.md CHANGED
@@ -36,6 +36,28 @@ To generate report, run
36
36
  ```bash
37
37
  sql_tracker tmp/sql_tracker-*.json
38
38
  ```
39
+ The output report looks like this:
40
+ ```
41
+ ==================================
42
+ Total Unique SQL Queries: 24
43
+ ==================================
44
+ Count | Avg Time (ms) | SQL Query | Source
45
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
46
+ 8 | 0.33 | SELECT `users`.* FROM `users` WHERE `users`.`id` = xxx LIMIT 1 | app/controllers/users_controller.rb:125:in `create'
47
+ | | | app/controllers/projects_controller.rb:9:in `block in update'
48
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
49
+ 4 | 0.27 | SELECT `projects`.* FROM `projects` WHERE `projects`.`user_id` = xxx AND `projects`.`id` = xxx LIMIT 1 | app/controllers/projects_controller.rb:4:in `update'
50
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
51
+ 2 | 0.27 | UPDATE `projects` SET `updated_at` = xxx WHERE `projects`.`id` = xxx | app/controllers/projects_controller.rb:9:in `block in update'
52
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
53
+ 2 | 1.76 | SELECT projects.* FROM projects WHERE projects.priority BETWEEN xxx AND xxx ORDER BY created_at DESC | app/controllers/projects_controller.rb:35:in `index'
54
+ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
55
+ ... ...
56
+ ```
57
+ By default, the report will be sorted by the total count of each query, you can also choose to sort it by average duration:
58
+ ```bash
59
+ sql_tracker tmp/sql_tracker-*.json --sort-by=duration
60
+ ```
39
61
 
40
62
  ## Configurations
41
63
 
data/bin/sql_tracker CHANGED
@@ -1,6 +1,24 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'sql_tracker/report'
3
3
  require 'json'
4
+ require 'optparse'
5
+
6
+ options = {}
7
+
8
+ parser = OptionParser.new(ARGV) do |o|
9
+ o.banner = 'Usage: sql_tracker [file.json]+ [--sort-by=COLUMN]'
10
+
11
+ o.on('-s', '--sort-by COLUMN', 'The name of column that is used for sorting the table. Options: count, duration') do |arg|
12
+ options[:sort_by] = arg if %(count duration).include?(arg)
13
+ end
14
+ end
15
+
16
+ parser.parse!
17
+ parser.abort(parser.help) if ARGV.empty?
18
+
19
+ default_options = { sort_by: 'count' }
20
+
21
+ options = default_options.merge(options)
4
22
 
5
23
  reports = []
6
24
  until ARGV.empty?
@@ -23,4 +41,4 @@ if reports.empty?
23
41
  end
24
42
 
25
43
  report = reports.inject(:+)
26
- report.print_text
44
+ report.print_text(options)
@@ -47,9 +47,12 @@ module SqlTracker
47
47
 
48
48
  def clean_sql_query(query)
49
49
  query.squish!
50
- query.gsub!(/(\s(=|>|<|>=|<=|<>|!=)\s)('[^']+'|\w+)/, '\1xxx')
50
+ query.gsub!(/(\s(=|>|<|>=|<=|<>|!=)\s)('[^']+'|[\$\+\-\w\.]+)/, '\1xxx')
51
51
  query.gsub!(/(\sIN\s)\([^\(\)]+\)/i, '\1(xxx)')
52
- query.gsub!(/(\sBETWEEN\s)('[^']+'|\w+)(\sAND\s)('[^']+'|\w+)/i, '\1xxx\3xxx')
52
+ query.gsub!(/(\sBETWEEN\s)('[^']+'|[\+\-\w\.]+)(\sAND\s)('[^']+'|[\+\-\w\.]+)/i, '\1xxx\3xxx')
53
+ query.gsub!(/(\sVALUES\s)\(.+\)/i, '\1(xxx)')
54
+ query.gsub!(/(\s(LIKE|ILIKE|SIMILAR TO|NOT SIMILAR TO)\s)('[^']+')/i, '\1xxx')
55
+ query.gsub!(/(\s(LIMIT|OFFSET)\s)(\d+)/i, '\1xxx')
53
56
  query
54
57
  end
55
58
 
@@ -25,7 +25,8 @@ module SqlTracker
25
25
  raw_data['data']
26
26
  end
27
27
 
28
- def print_text(f = STDOUT)
28
+ def print_text(options)
29
+ f = STDOUT
29
30
  f.puts '=================================='
30
31
  f.puts "Total Unique SQL Queries: #{data.keys.size}"
31
32
  f.puts '=================================='
@@ -35,7 +36,8 @@ module SqlTracker
35
36
  )
36
37
  f.puts '-' * terminal_width
37
38
 
38
- data.values.sort_by { |d| -d['count'] }.each do |row|
39
+ sorted_data = sort_data(data.values, options[:sort_by])
40
+ sorted_data.each do |row|
39
41
  chopped_sql = wrap_text(row['sql'], sql_width)
40
42
  source_list = wrap_list(row['source'].uniq, sql_width - 10)
41
43
  avg_duration = row['duration'].to_f / row['count']
@@ -50,15 +52,26 @@ module SqlTracker
50
52
  duration = line == 0 ? avg_duration.round(2) : ''
51
53
  source = source_list.length > line ? source_list[line] : ''
52
54
  query = row['sql'].length > line ? chopped_sql[line] : ''
53
- f.printf(
54
- "%-#{count_width}s | %-#{duration_width}s | %-#{sql_width}s | %-#{sql_width}s\n",
55
- count, duration, query, source
56
- )
55
+ f.printf(row_format, count, duration, query, source)
57
56
  end
58
57
  f.puts '-' * terminal_width
59
58
  end
60
59
  end
61
60
 
61
+ def row_format
62
+ "%-#{count_width}s | %-#{duration_width}s | %-#{sql_width}s | %-#{sql_width}s\n"
63
+ end
64
+
65
+ def sort_data(data, sort_by)
66
+ data.sort_by do |d|
67
+ if sort_by == 'duration'
68
+ -d['duration'].to_f / d['count']
69
+ else
70
+ -d['count']
71
+ end
72
+ end
73
+ end
74
+
62
75
  def +(other)
63
76
  unless self.class == other.class
64
77
  raise ArgumentError, "cannot combine #{other.class}"
@@ -1,3 +1,3 @@
1
1
  module SqlTracker
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '1.2.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sql_tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Yue
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-03 00:00:00.000000000 Z
11
+ date: 2016-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler