simple-sql 0.4.28 → 0.4.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -1
- data/config/console-init.rb +2 -0
- data/lib/simple/sql/config.rb +1 -0
- data/lib/simple/sql/connection_adapter.rb +4 -2
- data/lib/simple/sql/duplicate.rb +1 -0
- data/lib/simple/sql/formatting.rb +60 -0
- data/lib/simple/sql/helpers/decoder.rb +1 -1
- data/lib/simple/sql/helpers/immutable.rb +3 -1
- data/lib/simple/sql/insert.rb +2 -0
- data/lib/simple/sql/logging.rb +60 -11
- data/lib/simple/sql/reflection.rb +1 -1
- data/lib/simple/sql/result/association_loader.rb +2 -0
- data/lib/simple/sql/result/records.rb +1 -1
- data/lib/simple/sql/scope/order.rb +0 -2
- data/lib/simple/sql/version.rb +1 -1
- data/simple-sql.gemspec +1 -1
- data/vendor/.gitignore +1 -0
- data/vendor/Makefile +4 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f70bf7c7bf33282cf573be0fe9371aab9839a7a2fb6e4b3266827871e667575
|
4
|
+
data.tar.gz: 5d857fdc4905fb3e5d40b6f51c1e978b4f92b3d7db30a133266d1c0daa72ce63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4626339a32bbad1585a8a50b746a55f939ecaf5f671d8b2511b4261446221c8a0be1ef9d2bcfd6193fef5427b3e0a7544af1c25362edca54c8e298f8bfb9d186
|
7
|
+
data.tar.gz: 994ddacac8809d15605e6a336699135d7c40361bdf6d7e9e667d618889e92f444b249cb228bf5e84d411762900c74651167d6c65ee6168b41c527baaca1f6bc0
|
data/.rubocop.yml
CHANGED
@@ -10,7 +10,7 @@ AllCops:
|
|
10
10
|
- 'Rakefile'
|
11
11
|
|
12
12
|
Metrics/LineLength:
|
13
|
-
Max:
|
13
|
+
Max: 140
|
14
14
|
|
15
15
|
Metrics/MethodLength:
|
16
16
|
Max: 20
|
@@ -72,3 +72,7 @@ Style/IfUnlessModifier:
|
|
72
72
|
|
73
73
|
Style/PerlBackrefs:
|
74
74
|
Enabled: false
|
75
|
+
|
76
|
+
Style/TrailingUnderscoreVariable:
|
77
|
+
Enabled: false
|
78
|
+
|
data/config/console-init.rb
CHANGED
data/lib/simple/sql/config.rb
CHANGED
@@ -12,7 +12,7 @@ module Simple::SQL::ConnectionAdapter
|
|
12
12
|
# arguments - since the pg client does not support this - but it allows to
|
13
13
|
# run multiple sql statements separated by ";"
|
14
14
|
def exec(sql)
|
15
|
-
Logging.
|
15
|
+
Logging.with_logged_query sql do
|
16
16
|
raw_connection.exec sql
|
17
17
|
end
|
18
18
|
end
|
@@ -33,6 +33,7 @@ module Simple::SQL::ConnectionAdapter
|
|
33
33
|
|
34
34
|
def all(sql, *args, into: nil, &block)
|
35
35
|
raise ArgumentError, "all no longer support blocks, use each instead." if block
|
36
|
+
|
36
37
|
rows = []
|
37
38
|
my_pg_source_oid = nil
|
38
39
|
|
@@ -67,6 +68,7 @@ module Simple::SQL::ConnectionAdapter
|
|
67
68
|
# Runs a query and prints the results via "table_print"
|
68
69
|
def print(sql, *args, into: nil)
|
69
70
|
raise ArgumentError, "You cannot call Simple::SQL.print with into: #{into.inspect}" unless into.nil?
|
71
|
+
|
70
72
|
require "table_print"
|
71
73
|
records = all sql, *args, into: Hash
|
72
74
|
tp records
|
@@ -117,7 +119,7 @@ module Simple::SQL::ConnectionAdapter
|
|
117
119
|
sql = sql_or_scope
|
118
120
|
end
|
119
121
|
|
120
|
-
Logging.
|
122
|
+
Logging.with_logged_query sql, *args do
|
121
123
|
raw_connection.exec_params(sql, Encoder.encode_args(raw_connection, args))
|
122
124
|
end
|
123
125
|
end
|
data/lib/simple/sql/duplicate.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Simple
|
2
|
+
module SQL
|
3
|
+
module Formatting
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def format(sql, *args)
|
7
|
+
sql = format_sql(sql)
|
8
|
+
|
9
|
+
return sql if args.empty?
|
10
|
+
|
11
|
+
args = args.map(&:inspect).join(", ")
|
12
|
+
sql += " w/args: #{args}"
|
13
|
+
sql = sql[0, 98] + "..." if sql.length > 100
|
14
|
+
sql
|
15
|
+
end
|
16
|
+
|
17
|
+
def pretty_format(sql, *args)
|
18
|
+
sql = if use_pg_format?
|
19
|
+
pg_format_sql(sql)
|
20
|
+
else
|
21
|
+
format_sql(sql)
|
22
|
+
end
|
23
|
+
|
24
|
+
args = args.map(&:inspect).join(", ")
|
25
|
+
"#{sql} w/args: #{args}"
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def format_sql(sql)
|
31
|
+
sql.gsub(/\s*\n\s*/, " ").gsub(/(\A\s+)|(\s+\z)/, "")
|
32
|
+
end
|
33
|
+
|
34
|
+
require "open3"
|
35
|
+
|
36
|
+
def use_pg_format?
|
37
|
+
return @use_pg_format unless @use_pg_format.nil?
|
38
|
+
|
39
|
+
`which pg_format`
|
40
|
+
if $?.exitstatus == 0
|
41
|
+
@use_pg_format = true
|
42
|
+
else
|
43
|
+
Simple::SQL.logger.warn "[sql] simple-sql can use pg_format for logging queries. Please see https://github.com/darold/pgFormatter"
|
44
|
+
@use_pg_format = false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
PG_FORMAT_ARGS = "--function-case 2 --maxlength 15000 --nocomment --spaces 2 --keyword-case 2 --no-comma-end"
|
49
|
+
|
50
|
+
def pg_format_sql(sql)
|
51
|
+
stdin, stdout, _ = Open3.popen2("pg_format #{PG_FORMAT_ARGS} -")
|
52
|
+
stdin.print sql
|
53
|
+
stdin.close
|
54
|
+
formatted = stdout.read
|
55
|
+
stdout.close
|
56
|
+
formatted
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -6,6 +6,7 @@ module Simple::SQL::Helpers::Decoder
|
|
6
6
|
|
7
7
|
# rubocop:disable Metrics/AbcSize
|
8
8
|
# rubocop:disable Metrics/CyclomaticComplexity
|
9
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
9
10
|
def decode_value(type, s)
|
10
11
|
case type
|
11
12
|
when :unknown then s
|
@@ -31,7 +32,6 @@ module Simple::SQL::Helpers::Decoder
|
|
31
32
|
end
|
32
33
|
# rubocop:enable Metrics/AbcSize
|
33
34
|
# rubocop:enable Metrics/CyclomaticComplexity
|
34
|
-
# rubocop:enable Metrics/MethodLength
|
35
35
|
|
36
36
|
require "pg_array_parser"
|
37
37
|
extend PgArrayParser
|
@@ -14,6 +14,7 @@ class Simple::SQL::Helpers::Immutable
|
|
14
14
|
case object
|
15
15
|
when Array
|
16
16
|
raise ArgumentError, "Object nested too deep (or inner loop?)" if max_depth < 0
|
17
|
+
|
17
18
|
object.map { |obj| create obj, max_depth - 1 }
|
18
19
|
when Hash
|
19
20
|
new(object)
|
@@ -65,6 +66,8 @@ end
|
|
65
66
|
|
66
67
|
if $PROGRAM_NAME == __FILE__
|
67
68
|
|
69
|
+
# rubocop:disable Metrics/AbcSize
|
70
|
+
|
68
71
|
require "test-unit"
|
69
72
|
|
70
73
|
class Simple::SQL::Helpers::Immutable::TestCase < Test::Unit::TestCase
|
@@ -146,5 +149,4 @@ if $PROGRAM_NAME == __FILE__
|
|
146
149
|
end
|
147
150
|
end
|
148
151
|
|
149
|
-
# rubocop:enable Style/ClassAndModuleChildren
|
150
152
|
end
|
data/lib/simple/sql/insert.rb
CHANGED
data/lib/simple/sql/logging.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# rubocop:disable Metrics/AbcSize
|
2
|
+
|
3
|
+
require_relative "formatting"
|
4
|
+
|
1
5
|
module Simple
|
2
6
|
module SQL
|
3
7
|
module Logging
|
@@ -25,7 +29,10 @@ module Simple
|
|
25
29
|
return logger if logger
|
26
30
|
end
|
27
31
|
|
28
|
-
|
32
|
+
stderr_logger
|
33
|
+
end
|
34
|
+
|
35
|
+
def stderr_logger
|
29
36
|
@stderr_logger ||= begin
|
30
37
|
logger = Logger.new(STDERR)
|
31
38
|
logger.level = Logger::INFO
|
@@ -38,25 +45,67 @@ module Simple
|
|
38
45
|
extend Forwardable
|
39
46
|
delegate [:debug, :info, :warn, :error, :fatal] => :logger
|
40
47
|
|
41
|
-
def
|
48
|
+
def slow_query_treshold
|
49
|
+
@slow_query_treshold
|
50
|
+
end
|
51
|
+
|
52
|
+
def slow_query_treshold=(slow_query_treshold)
|
53
|
+
expect! slow_query_treshold > 0
|
54
|
+
@slow_query_treshold = slow_query_treshold
|
55
|
+
end
|
56
|
+
|
57
|
+
def with_logged_query(sql, *args, &_block)
|
42
58
|
r0 = Time.now
|
43
59
|
rv = yield
|
44
|
-
|
45
|
-
|
60
|
+
runtime = Time.now - r0
|
61
|
+
|
62
|
+
logger.debug do
|
63
|
+
"[sql] %.3f secs: %s" % [runtime, Formatting.format(sql, *args)]
|
64
|
+
end
|
65
|
+
|
66
|
+
if slow_query_treshold && runtime > slow_query_treshold
|
67
|
+
log_slow_query(sql, *args, runtime: runtime)
|
68
|
+
end
|
69
|
+
|
46
70
|
rv
|
47
71
|
rescue StandardError => e
|
48
|
-
|
49
|
-
warn
|
72
|
+
runtime = Time.now - r0
|
73
|
+
logger.warn do
|
74
|
+
"[sql] %.3f secs: %s:\n\tfailed with error %s" % [runtime, Formatting.format(sql, *args), e.message]
|
75
|
+
end
|
76
|
+
|
50
77
|
raise
|
51
78
|
end
|
52
79
|
|
53
80
|
private
|
54
81
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
82
|
+
Formatting = ::Simple::SQL::Formatting
|
83
|
+
|
84
|
+
def log_slow_query(sql, *args, runtime:)
|
85
|
+
# Do not try to analyze an EXPLAIN query. This prevents endless recursion here
|
86
|
+
# (and, in general, would not be useful anyways.)
|
87
|
+
return if sql =~ /^EXPLAIN /
|
88
|
+
|
89
|
+
log_multiple_lines ::Logger::WARN, prefix: "[sql-slow]" do
|
90
|
+
formatted_query = Formatting.pretty_format(sql, *args)
|
91
|
+
query_plan = ::Simple::SQL.all "EXPLAIN ANALYZE #{sql}", *args
|
92
|
+
|
93
|
+
<<~MSG
|
94
|
+
=== slow query detected: (#{'%.3f secs' % runtime}) ===================================================================================
|
95
|
+
#{formatted_query}
|
96
|
+
--- query plan: -------------------------------------------------------------------
|
97
|
+
#{query_plan.join("\n")}
|
98
|
+
===================================================================================
|
99
|
+
MSG
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def log_multiple_lines(level, str = nil, prefix:)
|
104
|
+
logger.log(level) do
|
105
|
+
str = yield if str.nil?
|
106
|
+
str = str.gsub("\n", "\n#{prefix} ") if prefix
|
107
|
+
str
|
108
|
+
end
|
60
109
|
end
|
61
110
|
end
|
62
111
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# rubocop:disable Metrics/MethodLength
|
3
3
|
# rubocop:disable Metrics/ParameterLists
|
4
4
|
# rubocop:disable Style/GuardClause
|
5
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
5
6
|
|
6
7
|
require "active_support/core_ext/string/inflections"
|
7
8
|
|
@@ -164,6 +165,7 @@ module ::Simple::SQL::Result::AssociationLoader # :nodoc:
|
|
164
165
|
if order_by || limit
|
165
166
|
raise ArgumentError, "#{association.inspect} is a singular association, w/o support for order_by: and limit:"
|
166
167
|
end
|
168
|
+
|
167
169
|
preload_belongs_to records, relation, as: as
|
168
170
|
else
|
169
171
|
preload_has_one_or_many records, relation, as: as, order_by: order_by, limit: limit
|
data/lib/simple/sql/version.rb
CHANGED
data/simple-sql.gemspec
CHANGED
@@ -38,7 +38,7 @@ Gem::Specification.new do |gem|
|
|
38
38
|
gem.add_development_dependency 'pg', '0.20'
|
39
39
|
gem.add_development_dependency 'rake', '~> 11'
|
40
40
|
gem.add_development_dependency 'rspec', '~> 3.7'
|
41
|
-
gem.add_development_dependency 'rubocop', '~> 0.
|
41
|
+
gem.add_development_dependency 'rubocop', '~> 0.61.1'
|
42
42
|
gem.add_development_dependency 'database_cleaner', '~> 1'
|
43
43
|
gem.add_development_dependency 'simplecov', '~> 0'
|
44
44
|
gem.add_development_dependency 'awesome_print', '~> 0'
|
data/vendor/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pgFormatter-3.1
|
data/vendor/Makefile
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-sql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.29
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-12-
|
12
|
+
date: 2018-12-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pg_array_parser
|
@@ -115,14 +115,14 @@ dependencies:
|
|
115
115
|
requirements:
|
116
116
|
- - "~>"
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version: 0.
|
118
|
+
version: 0.61.1
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
123
|
- - "~>"
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: 0.
|
125
|
+
version: 0.61.1
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: database_cleaner
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -203,6 +203,7 @@ files:
|
|
203
203
|
- lib/simple/sql/connection.rb
|
204
204
|
- lib/simple/sql/connection_adapter.rb
|
205
205
|
- lib/simple/sql/duplicate.rb
|
206
|
+
- lib/simple/sql/formatting.rb
|
206
207
|
- lib/simple/sql/helpers.rb
|
207
208
|
- lib/simple/sql/helpers/decoder.rb
|
208
209
|
- lib/simple/sql/helpers/encoder.rb
|
@@ -245,6 +246,8 @@ files:
|
|
245
246
|
- spec/support/004_simplecov.rb
|
246
247
|
- spec/support/model/user.rb
|
247
248
|
- tasks/release.rake
|
249
|
+
- vendor/.gitignore
|
250
|
+
- vendor/Makefile
|
248
251
|
homepage: http://github.com/radiospiel/simple-sql
|
249
252
|
licenses: []
|
250
253
|
metadata: {}
|